Add Turntable.cpp to SCons build.
Set native eol-style on recently added files. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6252 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
@@ -1,32 +1,32 @@
|
|||||||
// Copyright (C) 2010 Dolphin Project.
|
// Copyright (C) 2010 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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/
|
||||||
|
|
||||||
#ifndef _CPUCOREBASE_H
|
#ifndef _CPUCOREBASE_H
|
||||||
#define _CPUCOREBASE_H
|
#define _CPUCOREBASE_H
|
||||||
|
|
||||||
class CPUCoreBase
|
class CPUCoreBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual void Init() = 0;
|
virtual void Init() = 0;
|
||||||
virtual void Shutdown() = 0;
|
virtual void Shutdown() = 0;
|
||||||
virtual void ClearCache() = 0;
|
virtual void ClearCache() = 0;
|
||||||
virtual void Run() = 0;
|
virtual void Run() = 0;
|
||||||
virtual void SingleStep() = 0;
|
virtual void SingleStep() = 0;
|
||||||
virtual const char *GetName() = 0;
|
virtual const char *GetName() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,158 +1,158 @@
|
|||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
|
||||||
#include "Statistics.h"
|
#include "Statistics.h"
|
||||||
#include "OpcodeDecoding.h"
|
#include "OpcodeDecoding.h"
|
||||||
#include "IndexGenerator.h"
|
#include "IndexGenerator.h"
|
||||||
|
|
||||||
#include "VertexManagerBase.h"
|
#include "VertexManagerBase.h"
|
||||||
|
|
||||||
VertexManager *g_vertex_manager;
|
VertexManager *g_vertex_manager;
|
||||||
|
|
||||||
u8 *VertexManager::s_pCurBufferPointer;
|
u8 *VertexManager::s_pCurBufferPointer;
|
||||||
u8 *VertexManager::s_pBaseBufferPointer;
|
u8 *VertexManager::s_pBaseBufferPointer;
|
||||||
|
|
||||||
u8 *VertexManager::LocalVBuffer;
|
u8 *VertexManager::LocalVBuffer;
|
||||||
u16 *VertexManager::TIBuffer;
|
u16 *VertexManager::TIBuffer;
|
||||||
u16 *VertexManager::LIBuffer;
|
u16 *VertexManager::LIBuffer;
|
||||||
u16 *VertexManager::PIBuffer;
|
u16 *VertexManager::PIBuffer;
|
||||||
|
|
||||||
bool VertexManager::Flushed;
|
bool VertexManager::Flushed;
|
||||||
|
|
||||||
VertexManager::VertexManager()
|
VertexManager::VertexManager()
|
||||||
{
|
{
|
||||||
Flushed = false;
|
Flushed = false;
|
||||||
|
|
||||||
LocalVBuffer = new u8[MAXVBUFFERSIZE];
|
LocalVBuffer = new u8[MAXVBUFFERSIZE];
|
||||||
s_pCurBufferPointer = s_pBaseBufferPointer = LocalVBuffer;
|
s_pCurBufferPointer = s_pBaseBufferPointer = LocalVBuffer;
|
||||||
|
|
||||||
TIBuffer = new u16[MAXIBUFFERSIZE];
|
TIBuffer = new u16[MAXIBUFFERSIZE];
|
||||||
LIBuffer = new u16[MAXIBUFFERSIZE];
|
LIBuffer = new u16[MAXIBUFFERSIZE];
|
||||||
PIBuffer = new u16[MAXIBUFFERSIZE];
|
PIBuffer = new u16[MAXIBUFFERSIZE];
|
||||||
|
|
||||||
IndexGenerator::Start(TIBuffer, LIBuffer, PIBuffer);
|
IndexGenerator::Start(TIBuffer, LIBuffer, PIBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexManager::ResetBuffer()
|
void VertexManager::ResetBuffer()
|
||||||
{
|
{
|
||||||
s_pCurBufferPointer = LocalVBuffer;
|
s_pCurBufferPointer = LocalVBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
VertexManager::~VertexManager()
|
VertexManager::~VertexManager()
|
||||||
{
|
{
|
||||||
delete[] LocalVBuffer;
|
delete[] LocalVBuffer;
|
||||||
|
|
||||||
delete[] TIBuffer;
|
delete[] TIBuffer;
|
||||||
delete[] LIBuffer;
|
delete[] LIBuffer;
|
||||||
delete[] PIBuffer;
|
delete[] PIBuffer;
|
||||||
|
|
||||||
// TODO: necessary??
|
// TODO: necessary??
|
||||||
ResetBuffer();
|
ResetBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexManager::AddIndices(int primitive, int numVertices)
|
void VertexManager::AddIndices(int primitive, int numVertices)
|
||||||
{
|
{
|
||||||
//switch (primitive)
|
//switch (primitive)
|
||||||
//{
|
//{
|
||||||
//case GX_DRAW_QUADS: IndexGenerator::AddQuads(numVertices); break;
|
//case GX_DRAW_QUADS: IndexGenerator::AddQuads(numVertices); break;
|
||||||
//case GX_DRAW_TRIANGLES: IndexGenerator::AddList(numVertices); break;
|
//case GX_DRAW_TRIANGLES: IndexGenerator::AddList(numVertices); break;
|
||||||
//case GX_DRAW_TRIANGLE_STRIP: IndexGenerator::AddStrip(numVertices); break;
|
//case GX_DRAW_TRIANGLE_STRIP: IndexGenerator::AddStrip(numVertices); break;
|
||||||
//case GX_DRAW_TRIANGLE_FAN: IndexGenerator::AddFan(numVertices); break;
|
//case GX_DRAW_TRIANGLE_FAN: IndexGenerator::AddFan(numVertices); break;
|
||||||
//case GX_DRAW_LINES: IndexGenerator::AddLineList(numVertices); break;
|
//case GX_DRAW_LINES: IndexGenerator::AddLineList(numVertices); break;
|
||||||
//case GX_DRAW_LINE_STRIP: IndexGenerator::AddLineStrip(numVertices); break;
|
//case GX_DRAW_LINE_STRIP: IndexGenerator::AddLineStrip(numVertices); break;
|
||||||
//case GX_DRAW_POINTS: IndexGenerator::AddPoints(numVertices); break;
|
//case GX_DRAW_POINTS: IndexGenerator::AddPoints(numVertices); break;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
static void (*const primitive_table[])(int) =
|
static void (*const primitive_table[])(int) =
|
||||||
{
|
{
|
||||||
IndexGenerator::AddQuads,
|
IndexGenerator::AddQuads,
|
||||||
NULL,
|
NULL,
|
||||||
IndexGenerator::AddList,
|
IndexGenerator::AddList,
|
||||||
IndexGenerator::AddStrip,
|
IndexGenerator::AddStrip,
|
||||||
IndexGenerator::AddFan,
|
IndexGenerator::AddFan,
|
||||||
IndexGenerator::AddLineList,
|
IndexGenerator::AddLineList,
|
||||||
IndexGenerator::AddLineStrip,
|
IndexGenerator::AddLineStrip,
|
||||||
IndexGenerator::AddPoints,
|
IndexGenerator::AddPoints,
|
||||||
};
|
};
|
||||||
|
|
||||||
primitive_table[primitive](numVertices);
|
primitive_table[primitive](numVertices);
|
||||||
}
|
}
|
||||||
|
|
||||||
int VertexManager::GetRemainingSize()
|
int VertexManager::GetRemainingSize()
|
||||||
{
|
{
|
||||||
return MAXVBUFFERSIZE - (int)(s_pCurBufferPointer - LocalVBuffer);
|
return MAXVBUFFERSIZE - (int)(s_pCurBufferPointer - LocalVBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
int VertexManager::GetRemainingVertices(int primitive)
|
int VertexManager::GetRemainingVertices(int primitive)
|
||||||
{
|
{
|
||||||
switch (primitive)
|
switch (primitive)
|
||||||
{
|
{
|
||||||
case GX_DRAW_QUADS:
|
case GX_DRAW_QUADS:
|
||||||
case GX_DRAW_TRIANGLES:
|
case GX_DRAW_TRIANGLES:
|
||||||
case GX_DRAW_TRIANGLE_STRIP:
|
case GX_DRAW_TRIANGLE_STRIP:
|
||||||
case GX_DRAW_TRIANGLE_FAN:
|
case GX_DRAW_TRIANGLE_FAN:
|
||||||
return (MAXIBUFFERSIZE - IndexGenerator::GetTriangleindexLen()) / 3;
|
return (MAXIBUFFERSIZE - IndexGenerator::GetTriangleindexLen()) / 3;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GX_DRAW_LINES:
|
case GX_DRAW_LINES:
|
||||||
case GX_DRAW_LINE_STRIP:
|
case GX_DRAW_LINE_STRIP:
|
||||||
return (MAXIBUFFERSIZE - IndexGenerator::GetLineindexLen()) / 2;
|
return (MAXIBUFFERSIZE - IndexGenerator::GetLineindexLen()) / 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GX_DRAW_POINTS:
|
case GX_DRAW_POINTS:
|
||||||
return (MAXIBUFFERSIZE - IndexGenerator::GetPointindexLen());
|
return (MAXIBUFFERSIZE - IndexGenerator::GetPointindexLen());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexManager::AddVertices(int primitive, int numVertices)
|
void VertexManager::AddVertices(int primitive, int numVertices)
|
||||||
{
|
{
|
||||||
if (numVertices <= 0)
|
if (numVertices <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch (primitive)
|
switch (primitive)
|
||||||
{
|
{
|
||||||
case GX_DRAW_QUADS:
|
case GX_DRAW_QUADS:
|
||||||
case GX_DRAW_TRIANGLES:
|
case GX_DRAW_TRIANGLES:
|
||||||
case GX_DRAW_TRIANGLE_STRIP:
|
case GX_DRAW_TRIANGLE_STRIP:
|
||||||
case GX_DRAW_TRIANGLE_FAN:
|
case GX_DRAW_TRIANGLE_FAN:
|
||||||
if (MAXIBUFFERSIZE - IndexGenerator::GetTriangleindexLen() < 3 * numVertices)
|
if (MAXIBUFFERSIZE - IndexGenerator::GetTriangleindexLen() < 3 * numVertices)
|
||||||
Flush();
|
Flush();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GX_DRAW_LINES:
|
case GX_DRAW_LINES:
|
||||||
case GX_DRAW_LINE_STRIP:
|
case GX_DRAW_LINE_STRIP:
|
||||||
if (MAXIBUFFERSIZE - IndexGenerator::GetLineindexLen() < 2 * numVertices)
|
if (MAXIBUFFERSIZE - IndexGenerator::GetLineindexLen() < 2 * numVertices)
|
||||||
Flush();
|
Flush();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GX_DRAW_POINTS:
|
case GX_DRAW_POINTS:
|
||||||
if (MAXIBUFFERSIZE - IndexGenerator::GetPointindexLen() < numVertices)
|
if (MAXIBUFFERSIZE - IndexGenerator::GetPointindexLen() < numVertices)
|
||||||
Flush();
|
Flush();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Flushed)
|
if (Flushed)
|
||||||
{
|
{
|
||||||
IndexGenerator::Start(TIBuffer, LIBuffer, PIBuffer);
|
IndexGenerator::Start(TIBuffer, LIBuffer, PIBuffer);
|
||||||
Flushed = false;
|
Flushed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ADDSTAT(stats.thisFrame.numPrims, numVertices);
|
ADDSTAT(stats.thisFrame.numPrims, numVertices);
|
||||||
INCSTAT(stats.thisFrame.numPrimitiveJoins);
|
INCSTAT(stats.thisFrame.numPrimitiveJoins);
|
||||||
AddIndices(primitive, numVertices);
|
AddIndices(primitive, numVertices);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: merge this func, (need to merge TextureCache)
|
// TODO: merge this func, (need to merge TextureCache)
|
||||||
void VertexManager::Flush()
|
void VertexManager::Flush()
|
||||||
{
|
{
|
||||||
g_vertex_manager->vFlush();
|
g_vertex_manager->vFlush();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,57 +1,57 @@
|
|||||||
|
|
||||||
#ifndef _VERTEXMANAGERBASE_H
|
#ifndef _VERTEXMANAGERBASE_H
|
||||||
#define _VERTEXMANAGERBASE_H
|
#define _VERTEXMANAGERBASE_H
|
||||||
|
|
||||||
class VertexManager
|
class VertexManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
// values from OGL plugin
|
// values from OGL plugin
|
||||||
//MAXVBUFFERSIZE = 0x1FFFF,
|
//MAXVBUFFERSIZE = 0x1FFFF,
|
||||||
//MAXIBUFFERSIZE = 0xFFFF,
|
//MAXIBUFFERSIZE = 0xFFFF,
|
||||||
|
|
||||||
// values from DX9 plugin
|
// values from DX9 plugin
|
||||||
//MAXVBUFFERSIZE = 0x50000,
|
//MAXVBUFFERSIZE = 0x50000,
|
||||||
//MAXIBUFFERSIZE = 0xFFFF,
|
//MAXIBUFFERSIZE = 0xFFFF,
|
||||||
|
|
||||||
// values from DX11 plugin
|
// values from DX11 plugin
|
||||||
MAXVBUFFERSIZE = 0x50000,
|
MAXVBUFFERSIZE = 0x50000,
|
||||||
MAXIBUFFERSIZE = 0x10000,
|
MAXIBUFFERSIZE = 0x10000,
|
||||||
};
|
};
|
||||||
|
|
||||||
VertexManager();
|
VertexManager();
|
||||||
virtual ~VertexManager(); // needs to be virtual for DX11's dtor
|
virtual ~VertexManager(); // needs to be virtual for DX11's dtor
|
||||||
|
|
||||||
static void AddVertices(int _primitive, int _numVertices);
|
static void AddVertices(int _primitive, int _numVertices);
|
||||||
|
|
||||||
// TODO: protected?
|
// TODO: protected?
|
||||||
static u8 *s_pCurBufferPointer;
|
static u8 *s_pCurBufferPointer;
|
||||||
static u8 *s_pBaseBufferPointer;
|
static u8 *s_pBaseBufferPointer;
|
||||||
|
|
||||||
static int GetRemainingSize();
|
static int GetRemainingSize();
|
||||||
static int GetRemainingVertices(int primitive);
|
static int GetRemainingVertices(int primitive);
|
||||||
|
|
||||||
static void Flush();
|
static void Flush();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// TODO: make private after Flush() is merged
|
// TODO: make private after Flush() is merged
|
||||||
static void ResetBuffer();
|
static void ResetBuffer();
|
||||||
|
|
||||||
static u8 *LocalVBuffer;
|
static u8 *LocalVBuffer;
|
||||||
static u16 *TIBuffer;
|
static u16 *TIBuffer;
|
||||||
static u16 *LIBuffer;
|
static u16 *LIBuffer;
|
||||||
static u16 *PIBuffer;
|
static u16 *PIBuffer;
|
||||||
|
|
||||||
static bool Flushed;
|
static bool Flushed;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void AddIndices(int primitive, int numVertices);
|
static void AddIndices(int primitive, int numVertices);
|
||||||
// temporary
|
// temporary
|
||||||
virtual void vFlush() = 0;
|
virtual void vFlush() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern VertexManager *g_vertex_manager;
|
extern VertexManager *g_vertex_manager;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,144 +1,144 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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/
|
||||||
|
|
||||||
// Common
|
// Common
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
|
||||||
// VideoCommon
|
// VideoCommon
|
||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
#include "BPFunctions.h"
|
#include "BPFunctions.h"
|
||||||
#include "Renderer.h"
|
#include "Renderer.h"
|
||||||
#include "VertexShaderManager.h"
|
#include "VertexShaderManager.h"
|
||||||
#include "VertexManager.h"
|
#include "VertexManager.h"
|
||||||
|
|
||||||
#include "Main.h"
|
#include "Main.h"
|
||||||
|
|
||||||
namespace BPFunctions
|
namespace BPFunctions
|
||||||
{
|
{
|
||||||
|
|
||||||
void FlushPipeline()
|
void FlushPipeline()
|
||||||
{
|
{
|
||||||
g_vertex_manager->Flush();
|
g_vertex_manager->Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetGenerationMode(const BPCmd &bp)
|
void SetGenerationMode(const BPCmd &bp)
|
||||||
{
|
{
|
||||||
g_renderer->SetGenerationMode();
|
g_renderer->SetGenerationMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetScissor(const BPCmd &bp)
|
void SetScissor(const BPCmd &bp)
|
||||||
{
|
{
|
||||||
g_renderer->SetScissorRect();
|
g_renderer->SetScissorRect();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetLineWidth(const BPCmd &bp)
|
void SetLineWidth(const BPCmd &bp)
|
||||||
{
|
{
|
||||||
g_renderer->SetLineWidth();
|
g_renderer->SetLineWidth();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetDepthMode(const BPCmd &bp)
|
void SetDepthMode(const BPCmd &bp)
|
||||||
{
|
{
|
||||||
g_renderer->SetDepthMode();
|
g_renderer->SetDepthMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetBlendMode(const BPCmd &bp)
|
void SetBlendMode(const BPCmd &bp)
|
||||||
{
|
{
|
||||||
g_renderer->SetBlendMode(false);
|
g_renderer->SetBlendMode(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetDitherMode(const BPCmd &bp)
|
void SetDitherMode(const BPCmd &bp)
|
||||||
{
|
{
|
||||||
g_renderer->SetDitherMode();
|
g_renderer->SetDitherMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetLogicOpMode(const BPCmd &bp)
|
void SetLogicOpMode(const BPCmd &bp)
|
||||||
{
|
{
|
||||||
g_renderer->SetLogicOpMode();
|
g_renderer->SetLogicOpMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetColorMask(const BPCmd &bp)
|
void SetColorMask(const BPCmd &bp)
|
||||||
{
|
{
|
||||||
g_renderer->SetColorMask();
|
g_renderer->SetColorMask();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CopyEFB(const BPCmd &bp, const EFBRectangle &rc, const u32 &address, const bool &fromZBuffer, const bool &isIntensityFmt, const u32 ©fmt, const int &scaleByHalf)
|
void CopyEFB(const BPCmd &bp, const EFBRectangle &rc, const u32 &address, const bool &fromZBuffer, const bool &isIntensityFmt, const u32 ©fmt, const int &scaleByHalf)
|
||||||
{
|
{
|
||||||
if (!g_ActiveConfig.bEFBCopyDisable)
|
if (!g_ActiveConfig.bEFBCopyDisable)
|
||||||
{
|
{
|
||||||
// if (g_ActiveConfig.bCopyEFBToTexture)
|
// if (g_ActiveConfig.bCopyEFBToTexture)
|
||||||
// {
|
// {
|
||||||
g_texture_cache->CopyRenderTargetToTexture(address, fromZBuffer, isIntensityFmt, copyfmt, !!scaleByHalf, rc);
|
g_texture_cache->CopyRenderTargetToTexture(address, fromZBuffer, isIntensityFmt, copyfmt, !!scaleByHalf, rc);
|
||||||
// }
|
// }
|
||||||
// else
|
// else
|
||||||
// {
|
// {
|
||||||
// PanicAlert("TODO: Implement EFB copying to RAM %s %d\n", __FILE__, __LINE__);
|
// PanicAlert("TODO: Implement EFB copying to RAM %s %d\n", __FILE__, __LINE__);
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClearScreen(const BPCmd &bp, const EFBRectangle &rc)
|
void ClearScreen(const BPCmd &bp, const EFBRectangle &rc)
|
||||||
{
|
{
|
||||||
bool colorEnable = bpmem.blendmode.colorupdate;
|
bool colorEnable = bpmem.blendmode.colorupdate;
|
||||||
bool alphaEnable = (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24 && bpmem.blendmode.alphaupdate);
|
bool alphaEnable = (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24 && bpmem.blendmode.alphaupdate);
|
||||||
bool zEnable = bpmem.zmode.updateenable;
|
bool zEnable = bpmem.zmode.updateenable;
|
||||||
|
|
||||||
if (colorEnable || alphaEnable || zEnable)
|
if (colorEnable || alphaEnable || zEnable)
|
||||||
{
|
{
|
||||||
u32 color = (bpmem.clearcolorAR << 16) | bpmem.clearcolorGB;
|
u32 color = (bpmem.clearcolorAR << 16) | bpmem.clearcolorGB;
|
||||||
u32 z = bpmem.clearZValue;
|
u32 z = bpmem.clearZValue;
|
||||||
|
|
||||||
g_renderer->ClearScreen(rc, colorEnable, alphaEnable, zEnable, color, z);
|
g_renderer->ClearScreen(rc, colorEnable, alphaEnable, zEnable, color, z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RestoreRenderState(const BPCmd &bp)
|
void RestoreRenderState(const BPCmd &bp)
|
||||||
{
|
{
|
||||||
g_renderer->RestoreAPIState();
|
g_renderer->RestoreAPIState();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetConfig(const int &type)
|
bool GetConfig(const int &type)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case CONFIG_ISWII:
|
case CONFIG_ISWII:
|
||||||
return g_VideoInitialize.bWii;
|
return g_VideoInitialize.bWii;
|
||||||
case CONFIG_DISABLEFOG:
|
case CONFIG_DISABLEFOG:
|
||||||
return g_ActiveConfig.bDisableFog;
|
return g_ActiveConfig.bDisableFog;
|
||||||
case CONFIG_SHOWEFBREGIONS:
|
case CONFIG_SHOWEFBREGIONS:
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
PanicAlert("GetConfig Error: Unknown Config Type!");
|
PanicAlert("GetConfig Error: Unknown Config Type!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 *GetPointer(const u32 &address)
|
u8 *GetPointer(const u32 &address)
|
||||||
{
|
{
|
||||||
return g_VideoInitialize.pGetMemoryPointer(address);
|
return g_VideoInitialize.pGetMemoryPointer(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetTextureMode(const BPCmd &bp)
|
void SetTextureMode(const BPCmd &bp)
|
||||||
{
|
{
|
||||||
g_renderer->SetSamplerState(bp.address & 3, (bp.address & 0xE0) == 0xA0);
|
g_renderer->SetSamplerState(bp.address & 3, (bp.address & 0xE0) == 0xA0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetInterlacingMode(const BPCmd &bp)
|
void SetInterlacingMode(const BPCmd &bp)
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,338 +1,338 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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/
|
||||||
|
|
||||||
// Common
|
// Common
|
||||||
#include "StringUtil.h"
|
#include "StringUtil.h"
|
||||||
|
|
||||||
// VideoCommon
|
// VideoCommon
|
||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
#include "XFStructs.h"
|
#include "XFStructs.h"
|
||||||
|
|
||||||
// DX11
|
// DX11
|
||||||
#include "DX11_D3DBase.h"
|
#include "DX11_D3DBase.h"
|
||||||
#include "DX11_D3DTexture.h"
|
#include "DX11_D3DTexture.h"
|
||||||
#include "DX11_D3DShader.h"
|
#include "DX11_D3DShader.h"
|
||||||
#include "DX11_Render.h"
|
#include "DX11_Render.h"
|
||||||
|
|
||||||
#include <D3Dcompiler.h>
|
#include <D3Dcompiler.h>
|
||||||
|
|
||||||
#pragma comment(lib, "dxguid.lib")
|
#pragma comment(lib, "dxguid.lib")
|
||||||
#pragma comment(lib, "d3d11.lib")
|
#pragma comment(lib, "d3d11.lib")
|
||||||
#pragma comment(lib, "dxgi.lib")
|
#pragma comment(lib, "dxgi.lib")
|
||||||
|
|
||||||
namespace DX11
|
namespace DX11
|
||||||
{
|
{
|
||||||
|
|
||||||
HINSTANCE hD3DXDll = NULL;
|
HINSTANCE hD3DXDll = NULL;
|
||||||
D3DX11COMPILEFROMMEMORYTYPE PD3DX11CompileFromMemory = NULL;
|
D3DX11COMPILEFROMMEMORYTYPE PD3DX11CompileFromMemory = NULL;
|
||||||
D3DX11FILTERTEXTURETYPE PD3DX11FilterTexture = NULL;
|
D3DX11FILTERTEXTURETYPE PD3DX11FilterTexture = NULL;
|
||||||
D3DX11SAVETEXTURETOFILEATYPE PD3DX11SaveTextureToFileA = NULL;
|
D3DX11SAVETEXTURETOFILEATYPE PD3DX11SaveTextureToFileA = NULL;
|
||||||
D3DX11SAVETEXTURETOFILEWTYPE PD3DX11SaveTextureToFileW = NULL;
|
D3DX11SAVETEXTURETOFILEWTYPE PD3DX11SaveTextureToFileW = NULL;
|
||||||
|
|
||||||
namespace D3D
|
namespace D3D
|
||||||
{
|
{
|
||||||
|
|
||||||
ID3D11Device* device = NULL;
|
ID3D11Device* device = NULL;
|
||||||
ID3D11DeviceContext* context = NULL;
|
ID3D11DeviceContext* context = NULL;
|
||||||
IDXGISwapChain* swapchain = NULL;
|
IDXGISwapChain* swapchain = NULL;
|
||||||
D3D_FEATURE_LEVEL featlevel;
|
D3D_FEATURE_LEVEL featlevel;
|
||||||
D3DTexture2D* backbuf = NULL;
|
D3DTexture2D* backbuf = NULL;
|
||||||
HWND hWnd;
|
HWND hWnd;
|
||||||
|
|
||||||
bool bgra_textures_supported;
|
bool bgra_textures_supported;
|
||||||
|
|
||||||
#define NUM_SUPPORTED_FEATURE_LEVELS 3
|
#define NUM_SUPPORTED_FEATURE_LEVELS 3
|
||||||
const D3D_FEATURE_LEVEL supported_feature_levels[NUM_SUPPORTED_FEATURE_LEVELS] = {
|
const D3D_FEATURE_LEVEL supported_feature_levels[NUM_SUPPORTED_FEATURE_LEVELS] = {
|
||||||
D3D_FEATURE_LEVEL_11_0,
|
D3D_FEATURE_LEVEL_11_0,
|
||||||
D3D_FEATURE_LEVEL_10_1,
|
D3D_FEATURE_LEVEL_10_1,
|
||||||
D3D_FEATURE_LEVEL_10_0
|
D3D_FEATURE_LEVEL_10_0
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned int xres, yres;
|
unsigned int xres, yres;
|
||||||
|
|
||||||
bool bFrameInProgress = false;
|
bool bFrameInProgress = false;
|
||||||
|
|
||||||
HRESULT Create(HWND wnd)
|
HRESULT Create(HWND wnd)
|
||||||
{
|
{
|
||||||
hWnd = wnd;
|
hWnd = wnd;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
RECT client;
|
RECT client;
|
||||||
GetClientRect(hWnd, &client);
|
GetClientRect(hWnd, &client);
|
||||||
xres = client.right - client.left;
|
xres = client.right - client.left;
|
||||||
yres = client.bottom - client.top;
|
yres = client.bottom - client.top;
|
||||||
|
|
||||||
// try to load D3DX11 first to check whether we have proper runtime support
|
// try to load D3DX11 first to check whether we have proper runtime support
|
||||||
// try to use the dll the plugin was compiled against first - don't bother about debug runtimes
|
// try to use the dll the plugin was compiled against first - don't bother about debug runtimes
|
||||||
hD3DXDll = LoadLibraryA(StringFromFormat("d3dx11_%d.dll", D3DX11_SDK_VERSION).c_str());
|
hD3DXDll = LoadLibraryA(StringFromFormat("d3dx11_%d.dll", D3DX11_SDK_VERSION).c_str());
|
||||||
if (!hD3DXDll)
|
if (!hD3DXDll)
|
||||||
{
|
{
|
||||||
// if that fails, use the dll which should be available in every SDK which officially supports DX11.
|
// if that fails, use the dll which should be available in every SDK which officially supports DX11.
|
||||||
hD3DXDll = LoadLibraryA("d3dx11_42.dll");
|
hD3DXDll = LoadLibraryA("d3dx11_42.dll");
|
||||||
if (!hD3DXDll)
|
if (!hD3DXDll)
|
||||||
{
|
{
|
||||||
MessageBoxA(NULL, "Failed to load d3dx11_42.dll, update your DX11 runtime, please", "Critical error", MB_OK | MB_ICONERROR);
|
MessageBoxA(NULL, "Failed to load d3dx11_42.dll, update your DX11 runtime, please", "Critical error", MB_OK | MB_ICONERROR);
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NOTICE_LOG(VIDEO, "Successfully loaded d3dx11_42.dll. If you're having trouble, try updating your DX runtime first.");
|
NOTICE_LOG(VIDEO, "Successfully loaded d3dx11_42.dll. If you're having trouble, try updating your DX runtime first.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NOTICE_LOG(VIDEO, "Successfully loaded %s.", StringFromFormat("d3dx11_%d.dll", D3DX11_SDK_VERSION).c_str());
|
NOTICE_LOG(VIDEO, "Successfully loaded %s.", StringFromFormat("d3dx11_%d.dll", D3DX11_SDK_VERSION).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
PD3DX11CompileFromMemory = (D3DX11COMPILEFROMMEMORYTYPE)GetProcAddress(hD3DXDll, "D3DX11CompileFromMemory");
|
PD3DX11CompileFromMemory = (D3DX11COMPILEFROMMEMORYTYPE)GetProcAddress(hD3DXDll, "D3DX11CompileFromMemory");
|
||||||
if (PD3DX11CompileFromMemory == NULL) MessageBoxA(NULL, "GetProcAddress failed for D3DX11CompileFromMemory!", "Critical error", MB_OK | MB_ICONERROR);
|
if (PD3DX11CompileFromMemory == NULL) MessageBoxA(NULL, "GetProcAddress failed for D3DX11CompileFromMemory!", "Critical error", MB_OK | MB_ICONERROR);
|
||||||
|
|
||||||
PD3DX11FilterTexture = (D3DX11FILTERTEXTURETYPE)GetProcAddress(hD3DXDll, "D3DX11FilterTexture");
|
PD3DX11FilterTexture = (D3DX11FILTERTEXTURETYPE)GetProcAddress(hD3DXDll, "D3DX11FilterTexture");
|
||||||
if (PD3DX11FilterTexture == NULL) MessageBoxA(NULL, "GetProcAddress failed for D3DX11FilterTexture!", "Critical error", MB_OK | MB_ICONERROR);
|
if (PD3DX11FilterTexture == NULL) MessageBoxA(NULL, "GetProcAddress failed for D3DX11FilterTexture!", "Critical error", MB_OK | MB_ICONERROR);
|
||||||
|
|
||||||
PD3DX11SaveTextureToFileA = (D3DX11SAVETEXTURETOFILEATYPE)GetProcAddress(hD3DXDll, "D3DX11SaveTextureToFileA");
|
PD3DX11SaveTextureToFileA = (D3DX11SAVETEXTURETOFILEATYPE)GetProcAddress(hD3DXDll, "D3DX11SaveTextureToFileA");
|
||||||
if (PD3DX11SaveTextureToFileA == NULL) MessageBoxA(NULL, "GetProcAddress failed for D3DX11SaveTextureToFileA!", "Critical error", MB_OK | MB_ICONERROR);
|
if (PD3DX11SaveTextureToFileA == NULL) MessageBoxA(NULL, "GetProcAddress failed for D3DX11SaveTextureToFileA!", "Critical error", MB_OK | MB_ICONERROR);
|
||||||
|
|
||||||
PD3DX11SaveTextureToFileW = (D3DX11SAVETEXTURETOFILEWTYPE)GetProcAddress(hD3DXDll, "D3DX11SaveTextureToFileW");
|
PD3DX11SaveTextureToFileW = (D3DX11SAVETEXTURETOFILEWTYPE)GetProcAddress(hD3DXDll, "D3DX11SaveTextureToFileW");
|
||||||
if (PD3DX11SaveTextureToFileW == NULL) MessageBoxA(NULL, "GetProcAddress failed for D3DX11SaveTextureToFileW!", "Critical error", MB_OK | MB_ICONERROR);
|
if (PD3DX11SaveTextureToFileW == NULL) MessageBoxA(NULL, "GetProcAddress failed for D3DX11SaveTextureToFileW!", "Critical error", MB_OK | MB_ICONERROR);
|
||||||
|
|
||||||
// D3DX11 is fine, initialize D3D11
|
// D3DX11 is fine, initialize D3D11
|
||||||
IDXGIFactory* factory;
|
IDXGIFactory* factory;
|
||||||
IDXGIAdapter* adapter;
|
IDXGIAdapter* adapter;
|
||||||
IDXGIOutput* output;
|
IDXGIOutput* output;
|
||||||
hr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory);
|
hr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory);
|
||||||
if (FAILED(hr)) MessageBox(wnd, _T("Failed to create IDXGIFactory object"), _T("Dolphin Direct3D 11 plugin"), MB_OK | MB_ICONERROR);
|
if (FAILED(hr)) MessageBox(wnd, _T("Failed to create IDXGIFactory object"), _T("Dolphin Direct3D 11 plugin"), MB_OK | MB_ICONERROR);
|
||||||
|
|
||||||
hr = factory->EnumAdapters(g_ActiveConfig.iAdapter, &adapter);
|
hr = factory->EnumAdapters(g_ActiveConfig.iAdapter, &adapter);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
// try using the first one
|
// try using the first one
|
||||||
hr = factory->EnumAdapters(0, &adapter);
|
hr = factory->EnumAdapters(0, &adapter);
|
||||||
if (FAILED(hr)) MessageBox(wnd, _T("Failed to enumerate adapters"), _T("Dolphin Direct3D 11 plugin"), MB_OK | MB_ICONERROR);
|
if (FAILED(hr)) MessageBox(wnd, _T("Failed to enumerate adapters"), _T("Dolphin Direct3D 11 plugin"), MB_OK | MB_ICONERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Make this configurable
|
// TODO: Make this configurable
|
||||||
hr = adapter->EnumOutputs(0, &output);
|
hr = adapter->EnumOutputs(0, &output);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
// try using the first one
|
// try using the first one
|
||||||
hr = adapter->EnumOutputs(0, &output);
|
hr = adapter->EnumOutputs(0, &output);
|
||||||
if (FAILED(hr)) MessageBox(wnd, _T("Failed to enumerate outputs"), _T("Dolphin Direct3D 11 plugin"), MB_OK | MB_ICONERROR);
|
if (FAILED(hr)) MessageBox(wnd, _T("Failed to enumerate outputs"), _T("Dolphin Direct3D 11 plugin"), MB_OK | MB_ICONERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
// this will need to be changed once multisampling gets implemented
|
// this will need to be changed once multisampling gets implemented
|
||||||
DXGI_SWAP_CHAIN_DESC swap_chain_desc;
|
DXGI_SWAP_CHAIN_DESC swap_chain_desc;
|
||||||
memset(&swap_chain_desc, 0, sizeof(swap_chain_desc));
|
memset(&swap_chain_desc, 0, sizeof(swap_chain_desc));
|
||||||
swap_chain_desc.BufferCount = 1;
|
swap_chain_desc.BufferCount = 1;
|
||||||
swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||||
swap_chain_desc.OutputWindow = wnd;
|
swap_chain_desc.OutputWindow = wnd;
|
||||||
swap_chain_desc.SampleDesc.Count = 1;
|
swap_chain_desc.SampleDesc.Count = 1;
|
||||||
swap_chain_desc.SampleDesc.Quality = 0;
|
swap_chain_desc.SampleDesc.Quality = 0;
|
||||||
swap_chain_desc.Windowed = TRUE;
|
swap_chain_desc.Windowed = TRUE;
|
||||||
|
|
||||||
DXGI_MODE_DESC mode_desc;
|
DXGI_MODE_DESC mode_desc;
|
||||||
memset(&mode_desc, 0, sizeof(mode_desc));
|
memset(&mode_desc, 0, sizeof(mode_desc));
|
||||||
mode_desc.Width = xres;
|
mode_desc.Width = xres;
|
||||||
mode_desc.Height = yres;
|
mode_desc.Height = yres;
|
||||||
mode_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
mode_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
mode_desc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
|
mode_desc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
|
||||||
hr = output->FindClosestMatchingMode(&mode_desc, &swap_chain_desc.BufferDesc, NULL);
|
hr = output->FindClosestMatchingMode(&mode_desc, &swap_chain_desc.BufferDesc, NULL);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
MessageBox(wnd, _T("Failed to find a supported video mode"), _T("Dolphin Direct3D 11 plugin"), MB_OK | MB_ICONERROR);
|
MessageBox(wnd, _T("Failed to find a supported video mode"), _T("Dolphin Direct3D 11 plugin"), MB_OK | MB_ICONERROR);
|
||||||
|
|
||||||
// forcing buffer resolution to xres and yres.. TODO: The new video mode might not actually be supported!
|
// forcing buffer resolution to xres and yres.. TODO: The new video mode might not actually be supported!
|
||||||
swap_chain_desc.BufferDesc.Width = xres;
|
swap_chain_desc.BufferDesc.Width = xres;
|
||||||
swap_chain_desc.BufferDesc.Height = yres;
|
swap_chain_desc.BufferDesc.Height = yres;
|
||||||
|
|
||||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||||
D3D11_CREATE_DEVICE_FLAG device_flags = (D3D11_CREATE_DEVICE_FLAG)(D3D11_CREATE_DEVICE_DEBUG|D3D11_CREATE_DEVICE_SINGLETHREADED);
|
D3D11_CREATE_DEVICE_FLAG device_flags = (D3D11_CREATE_DEVICE_FLAG)(D3D11_CREATE_DEVICE_DEBUG|D3D11_CREATE_DEVICE_SINGLETHREADED);
|
||||||
#else
|
#else
|
||||||
D3D11_CREATE_DEVICE_FLAG device_flags = D3D11_CREATE_DEVICE_SINGLETHREADED;
|
D3D11_CREATE_DEVICE_FLAG device_flags = D3D11_CREATE_DEVICE_SINGLETHREADED;
|
||||||
#endif
|
#endif
|
||||||
hr = D3D11CreateDeviceAndSwapChain(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, device_flags,
|
hr = D3D11CreateDeviceAndSwapChain(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, device_flags,
|
||||||
supported_feature_levels, NUM_SUPPORTED_FEATURE_LEVELS,
|
supported_feature_levels, NUM_SUPPORTED_FEATURE_LEVELS,
|
||||||
D3D11_SDK_VERSION, &swap_chain_desc, &swapchain, &device,
|
D3D11_SDK_VERSION, &swap_chain_desc, &swapchain, &device,
|
||||||
&featlevel, &context);
|
&featlevel, &context);
|
||||||
if (FAILED(hr) || !device || !context || !swapchain)
|
if (FAILED(hr) || !device || !context || !swapchain)
|
||||||
{
|
{
|
||||||
MessageBox(wnd, _T("Failed to initialize Direct3D.\nMake sure your video card supports at least D3D 10.0"), _T("Dolphin Direct3D 11 plugin"), MB_OK | MB_ICONERROR);
|
MessageBox(wnd, _T("Failed to initialize Direct3D.\nMake sure your video card supports at least D3D 10.0"), _T("Dolphin Direct3D 11 plugin"), MB_OK | MB_ICONERROR);
|
||||||
SAFE_RELEASE(device);
|
SAFE_RELEASE(device);
|
||||||
SAFE_RELEASE(context);
|
SAFE_RELEASE(context);
|
||||||
SAFE_RELEASE(swapchain);
|
SAFE_RELEASE(swapchain);
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
SetDebugObjectName((ID3D11DeviceChild*)context, "device context");
|
SetDebugObjectName((ID3D11DeviceChild*)context, "device context");
|
||||||
SAFE_RELEASE(factory);
|
SAFE_RELEASE(factory);
|
||||||
SAFE_RELEASE(output);
|
SAFE_RELEASE(output);
|
||||||
SAFE_RELEASE(adapter);
|
SAFE_RELEASE(adapter);
|
||||||
|
|
||||||
ID3D11Texture2D* buf;
|
ID3D11Texture2D* buf;
|
||||||
hr = swapchain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&buf);
|
hr = swapchain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&buf);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
MessageBox(wnd, _T("Failed to get swapchain buffer"), _T("Dolphin Direct3D 11 plugin"), MB_OK | MB_ICONERROR);
|
MessageBox(wnd, _T("Failed to get swapchain buffer"), _T("Dolphin Direct3D 11 plugin"), MB_OK | MB_ICONERROR);
|
||||||
SAFE_RELEASE(device);
|
SAFE_RELEASE(device);
|
||||||
SAFE_RELEASE(context);
|
SAFE_RELEASE(context);
|
||||||
SAFE_RELEASE(swapchain);
|
SAFE_RELEASE(swapchain);
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
backbuf = new D3DTexture2D(buf, D3D11_BIND_RENDER_TARGET);
|
backbuf = new D3DTexture2D(buf, D3D11_BIND_RENDER_TARGET);
|
||||||
SAFE_RELEASE(buf);
|
SAFE_RELEASE(buf);
|
||||||
CHECK(backbuf!=NULL, "Create back buffer texture");
|
CHECK(backbuf!=NULL, "Create back buffer texture");
|
||||||
SetDebugObjectName((ID3D11DeviceChild*)backbuf->GetTex(), "backbuffer texture");
|
SetDebugObjectName((ID3D11DeviceChild*)backbuf->GetTex(), "backbuffer texture");
|
||||||
SetDebugObjectName((ID3D11DeviceChild*)backbuf->GetRTV(), "backbuffer render target view");
|
SetDebugObjectName((ID3D11DeviceChild*)backbuf->GetRTV(), "backbuffer render target view");
|
||||||
|
|
||||||
context->OMSetRenderTargets(1, &backbuf->GetRTV(), NULL);
|
context->OMSetRenderTargets(1, &backbuf->GetRTV(), NULL);
|
||||||
|
|
||||||
// BGRA textures are easier to deal with in TextureCache, but might not be supported by the hardware
|
// BGRA textures are easier to deal with in TextureCache, but might not be supported by the hardware
|
||||||
UINT format_support;
|
UINT format_support;
|
||||||
device->CheckFormatSupport(DXGI_FORMAT_B8G8R8A8_UNORM, &format_support);
|
device->CheckFormatSupport(DXGI_FORMAT_B8G8R8A8_UNORM, &format_support);
|
||||||
bgra_textures_supported = (format_support & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0;
|
bgra_textures_supported = (format_support & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0;
|
||||||
|
|
||||||
gfxstate = new EmuGfxState;
|
gfxstate = new EmuGfxState;
|
||||||
stateman = new StateManager;
|
stateman = new StateManager;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Close()
|
void Close()
|
||||||
{
|
{
|
||||||
// unload D3DX11
|
// unload D3DX11
|
||||||
FreeLibrary(hD3DXDll);
|
FreeLibrary(hD3DXDll);
|
||||||
PD3DX11FilterTexture = NULL;
|
PD3DX11FilterTexture = NULL;
|
||||||
PD3DX11SaveTextureToFileA = NULL;
|
PD3DX11SaveTextureToFileA = NULL;
|
||||||
PD3DX11SaveTextureToFileW = NULL;
|
PD3DX11SaveTextureToFileW = NULL;
|
||||||
|
|
||||||
// release all bound resources
|
// release all bound resources
|
||||||
context->ClearState();
|
context->ClearState();
|
||||||
SAFE_RELEASE(backbuf);
|
SAFE_RELEASE(backbuf);
|
||||||
SAFE_RELEASE(swapchain);
|
SAFE_RELEASE(swapchain);
|
||||||
SAFE_DELETE(gfxstate);
|
SAFE_DELETE(gfxstate);
|
||||||
SAFE_DELETE(stateman);
|
SAFE_DELETE(stateman);
|
||||||
context->Flush(); // immediately destroy device objects
|
context->Flush(); // immediately destroy device objects
|
||||||
|
|
||||||
SAFE_RELEASE(context);
|
SAFE_RELEASE(context);
|
||||||
ULONG references = device->Release();
|
ULONG references = device->Release();
|
||||||
if (references)
|
if (references)
|
||||||
{
|
{
|
||||||
ERROR_LOG(VIDEO, "Unreleased references: %i.", references);
|
ERROR_LOG(VIDEO, "Unreleased references: %i.", references);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NOTICE_LOG(VIDEO, "Successfully released all device references!");
|
NOTICE_LOG(VIDEO, "Successfully released all device references!");
|
||||||
}
|
}
|
||||||
device = NULL;
|
device = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* just returning the 4_0 ones here */
|
/* just returning the 4_0 ones here */
|
||||||
const char* VertexShaderVersionString() { return "vs_4_0"; }
|
const char* VertexShaderVersionString() { return "vs_4_0"; }
|
||||||
const char* PixelShaderVersionString() { return "ps_4_0"; }
|
const char* PixelShaderVersionString() { return "ps_4_0"; }
|
||||||
|
|
||||||
D3DTexture2D* &GetBackBuffer() { return backbuf; }
|
D3DTexture2D* &GetBackBuffer() { return backbuf; }
|
||||||
unsigned int GetBackBufferWidth() { return xres; }
|
unsigned int GetBackBufferWidth() { return xres; }
|
||||||
unsigned int GetBackBufferHeight() { return yres; }
|
unsigned int GetBackBufferHeight() { return yres; }
|
||||||
|
|
||||||
bool BGRATexturesSupported() { return bgra_textures_supported; }
|
bool BGRATexturesSupported() { return bgra_textures_supported; }
|
||||||
|
|
||||||
// Returns the maximum width/height of a texture. This value only depends upon the feature level in DX11
|
// Returns the maximum width/height of a texture. This value only depends upon the feature level in DX11
|
||||||
unsigned int GetMaxTextureSize()
|
unsigned int GetMaxTextureSize()
|
||||||
{
|
{
|
||||||
switch (featlevel)
|
switch (featlevel)
|
||||||
{
|
{
|
||||||
case D3D_FEATURE_LEVEL_11_0:
|
case D3D_FEATURE_LEVEL_11_0:
|
||||||
return 16384;
|
return 16384;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case D3D_FEATURE_LEVEL_10_1:
|
case D3D_FEATURE_LEVEL_10_1:
|
||||||
case D3D_FEATURE_LEVEL_10_0:
|
case D3D_FEATURE_LEVEL_10_0:
|
||||||
return 8192;
|
return 8192;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case D3D_FEATURE_LEVEL_9_3:
|
case D3D_FEATURE_LEVEL_9_3:
|
||||||
return 4096;
|
return 4096;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case D3D_FEATURE_LEVEL_9_2:
|
case D3D_FEATURE_LEVEL_9_2:
|
||||||
case D3D_FEATURE_LEVEL_9_1:
|
case D3D_FEATURE_LEVEL_9_1:
|
||||||
return 2048;
|
return 2048;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reset()
|
void Reset()
|
||||||
{
|
{
|
||||||
// release all back buffer references
|
// release all back buffer references
|
||||||
SAFE_RELEASE(backbuf);
|
SAFE_RELEASE(backbuf);
|
||||||
|
|
||||||
// resize swapchain buffers
|
// resize swapchain buffers
|
||||||
RECT client;
|
RECT client;
|
||||||
GetClientRect(hWnd, &client);
|
GetClientRect(hWnd, &client);
|
||||||
xres = client.right - client.left;
|
xres = client.right - client.left;
|
||||||
yres = client.bottom - client.top;
|
yres = client.bottom - client.top;
|
||||||
D3D::swapchain->ResizeBuffers(1, xres, yres, DXGI_FORMAT_R8G8B8A8_UNORM, 0);
|
D3D::swapchain->ResizeBuffers(1, xres, yres, DXGI_FORMAT_R8G8B8A8_UNORM, 0);
|
||||||
|
|
||||||
// recreate back buffer texture
|
// recreate back buffer texture
|
||||||
ID3D11Texture2D* buf;
|
ID3D11Texture2D* buf;
|
||||||
HRESULT hr = swapchain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&buf);
|
HRESULT hr = swapchain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&buf);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
MessageBox(hWnd, _T("Failed to get swapchain buffer"), _T("Dolphin Direct3D 11 plugin"), MB_OK | MB_ICONERROR);
|
MessageBox(hWnd, _T("Failed to get swapchain buffer"), _T("Dolphin Direct3D 11 plugin"), MB_OK | MB_ICONERROR);
|
||||||
SAFE_RELEASE(device);
|
SAFE_RELEASE(device);
|
||||||
SAFE_RELEASE(context);
|
SAFE_RELEASE(context);
|
||||||
SAFE_RELEASE(swapchain);
|
SAFE_RELEASE(swapchain);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
backbuf = new D3DTexture2D(buf, D3D11_BIND_RENDER_TARGET);
|
backbuf = new D3DTexture2D(buf, D3D11_BIND_RENDER_TARGET);
|
||||||
SAFE_RELEASE(buf);
|
SAFE_RELEASE(buf);
|
||||||
CHECK(backbuf!=NULL, "Create back buffer texture");
|
CHECK(backbuf!=NULL, "Create back buffer texture");
|
||||||
SetDebugObjectName((ID3D11DeviceChild*)backbuf->GetTex(), "backbuffer texture");
|
SetDebugObjectName((ID3D11DeviceChild*)backbuf->GetTex(), "backbuffer texture");
|
||||||
SetDebugObjectName((ID3D11DeviceChild*)backbuf->GetRTV(), "backbuffer render target view");
|
SetDebugObjectName((ID3D11DeviceChild*)backbuf->GetRTV(), "backbuffer render target view");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BeginFrame()
|
bool BeginFrame()
|
||||||
{
|
{
|
||||||
if (bFrameInProgress)
|
if (bFrameInProgress)
|
||||||
{
|
{
|
||||||
PanicAlert("BeginFrame called although a frame is already in progress");
|
PanicAlert("BeginFrame called although a frame is already in progress");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bFrameInProgress = true;
|
bFrameInProgress = true;
|
||||||
return (device != NULL);
|
return (device != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EndFrame()
|
void EndFrame()
|
||||||
{
|
{
|
||||||
if (!bFrameInProgress)
|
if (!bFrameInProgress)
|
||||||
{
|
{
|
||||||
PanicAlert("EndFrame called although no frame is in progress");
|
PanicAlert("EndFrame called although no frame is in progress");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bFrameInProgress = false;
|
bFrameInProgress = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Present()
|
void Present()
|
||||||
{
|
{
|
||||||
// TODO: Is 1 the correct value for vsyncing?
|
// TODO: Is 1 the correct value for vsyncing?
|
||||||
swapchain->Present((UINT)g_ActiveConfig.bVSync, 0);
|
swapchain->Present((UINT)g_ActiveConfig.bVSync, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,96 +1,96 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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
|
#pragma once
|
||||||
|
|
||||||
// Common
|
// Common
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
|
||||||
// DX11
|
// DX11
|
||||||
#include <d3dx11.h>
|
#include <d3dx11.h>
|
||||||
#include "DX11_GfxState.h"
|
#include "DX11_GfxState.h"
|
||||||
#include "DX11_D3DBlob.h"
|
#include "DX11_D3DBlob.h"
|
||||||
|
|
||||||
namespace DX11
|
namespace DX11
|
||||||
{
|
{
|
||||||
|
|
||||||
#define SAFE_RELEASE(x) { if (x) (x)->Release(); (x) = NULL; }
|
#define SAFE_RELEASE(x) { if (x) (x)->Release(); (x) = NULL; }
|
||||||
#define SAFE_DELETE(x) { delete (x); (x) = NULL; }
|
#define SAFE_DELETE(x) { delete (x); (x) = NULL; }
|
||||||
#define SAFE_DELETE_ARRAY(x) { delete[] (x); (x) = NULL; }
|
#define SAFE_DELETE_ARRAY(x) { delete[] (x); (x) = NULL; }
|
||||||
#define CHECK(cond, Message, ...) if (!(cond)) { PanicAlert(__FUNCTION__ "Failed in %s at line %d: " Message, __FILE__, __LINE__, __VA_ARGS__); }
|
#define CHECK(cond, Message, ...) if (!(cond)) { PanicAlert(__FUNCTION__ "Failed in %s at line %d: " Message, __FILE__, __LINE__, __VA_ARGS__); }
|
||||||
|
|
||||||
class D3DTexture2D;
|
class D3DTexture2D;
|
||||||
namespace D3D
|
namespace D3D
|
||||||
{
|
{
|
||||||
|
|
||||||
HRESULT Create(HWND wnd);
|
HRESULT Create(HWND wnd);
|
||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
extern ID3D11Device* device;
|
extern ID3D11Device* device;
|
||||||
extern ID3D11DeviceContext* context;
|
extern ID3D11DeviceContext* context;
|
||||||
extern IDXGISwapChain* swapchain;
|
extern IDXGISwapChain* swapchain;
|
||||||
extern bool bFrameInProgress;
|
extern bool bFrameInProgress;
|
||||||
|
|
||||||
void Reset();
|
void Reset();
|
||||||
bool BeginFrame();
|
bool BeginFrame();
|
||||||
void EndFrame();
|
void EndFrame();
|
||||||
void Present();
|
void Present();
|
||||||
|
|
||||||
unsigned int GetBackBufferWidth();
|
unsigned int GetBackBufferWidth();
|
||||||
unsigned int GetBackBufferHeight();
|
unsigned int GetBackBufferHeight();
|
||||||
D3DTexture2D* &GetBackBuffer();
|
D3DTexture2D* &GetBackBuffer();
|
||||||
const char* PixelShaderVersionString();
|
const char* PixelShaderVersionString();
|
||||||
const char* VertexShaderVersionString();
|
const char* VertexShaderVersionString();
|
||||||
bool BGRATexturesSupported();
|
bool BGRATexturesSupported();
|
||||||
|
|
||||||
unsigned int GetMaxTextureSize();
|
unsigned int GetMaxTextureSize();
|
||||||
|
|
||||||
// Ihis function will assign a name to the given resource.
|
// Ihis function will assign a name to the given resource.
|
||||||
// The DirectX debug layer will make it easier to identify resources that way,
|
// The DirectX debug layer will make it easier to identify resources that way,
|
||||||
// e.g. when listing up all resources who have unreleased references.
|
// e.g. when listing up all resources who have unreleased references.
|
||||||
inline void SetDebugObjectName(ID3D11DeviceChild* resource, const char* name)
|
inline void SetDebugObjectName(ID3D11DeviceChild* resource, const char* name)
|
||||||
{
|
{
|
||||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||||
resource->SetPrivateData( WKPDID_D3DDebugObjectName, (UINT)strlen(name), name);
|
resource->SetPrivateData( WKPDID_D3DDebugObjectName, (UINT)strlen(name), name);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
// Used to not require the SDK and runtime versions to match:
|
// Used to not require the SDK and runtime versions to match:
|
||||||
// Linking with d3dx11.lib makes the most recent d3dx11_xx.dll of the
|
// Linking with d3dx11.lib makes the most recent d3dx11_xx.dll of the
|
||||||
// compiler's SDK a requirement, but this plugin works with DX11 runtimes
|
// compiler's SDK a requirement, but this plugin works with DX11 runtimes
|
||||||
// back to August 2009 even if the plugin was built with June 2010.
|
// back to August 2009 even if the plugin was built with June 2010.
|
||||||
// Add any d3dx11 functions which you want to use here and load them in Create()
|
// Add any d3dx11 functions which you want to use here and load them in Create()
|
||||||
typedef HRESULT (WINAPI* D3DX11COMPILEFROMMEMORYTYPE)(LPCSTR, SIZE_T, LPCSTR, const D3D10_SHADER_MACRO*, LPD3D10INCLUDE, LPCSTR, LPCSTR, UINT, UINT, ID3DX11ThreadPump*, ID3D10Blob**, ID3D10Blob**, HRESULT*);
|
typedef HRESULT (WINAPI* D3DX11COMPILEFROMMEMORYTYPE)(LPCSTR, SIZE_T, LPCSTR, const D3D10_SHADER_MACRO*, LPD3D10INCLUDE, LPCSTR, LPCSTR, UINT, UINT, ID3DX11ThreadPump*, ID3D10Blob**, ID3D10Blob**, HRESULT*);
|
||||||
typedef HRESULT (WINAPI* D3DX11FILTERTEXTURETYPE)(ID3D11DeviceContext*, ID3D11Resource*, UINT, UINT);
|
typedef HRESULT (WINAPI* D3DX11FILTERTEXTURETYPE)(ID3D11DeviceContext*, ID3D11Resource*, UINT, UINT);
|
||||||
typedef HRESULT (WINAPI* D3DX11SAVETEXTURETOFILEATYPE)(ID3D11DeviceContext*, ID3D11Resource*, D3DX11_IMAGE_FILE_FORMAT, LPCSTR);
|
typedef HRESULT (WINAPI* D3DX11SAVETEXTURETOFILEATYPE)(ID3D11DeviceContext*, ID3D11Resource*, D3DX11_IMAGE_FILE_FORMAT, LPCSTR);
|
||||||
typedef HRESULT (WINAPI* D3DX11SAVETEXTURETOFILEWTYPE)(ID3D11DeviceContext*, ID3D11Resource*, D3DX11_IMAGE_FILE_FORMAT, LPCWSTR);
|
typedef HRESULT (WINAPI* D3DX11SAVETEXTURETOFILEWTYPE)(ID3D11DeviceContext*, ID3D11Resource*, D3DX11_IMAGE_FILE_FORMAT, LPCWSTR);
|
||||||
|
|
||||||
extern D3DX11COMPILEFROMMEMORYTYPE PD3DX11CompileFromMemory;
|
extern D3DX11COMPILEFROMMEMORYTYPE PD3DX11CompileFromMemory;
|
||||||
extern D3DX11FILTERTEXTURETYPE PD3DX11FilterTexture;
|
extern D3DX11FILTERTEXTURETYPE PD3DX11FilterTexture;
|
||||||
extern D3DX11SAVETEXTURETOFILEATYPE PD3DX11SaveTextureToFileA;
|
extern D3DX11SAVETEXTURETOFILEATYPE PD3DX11SaveTextureToFileA;
|
||||||
extern D3DX11SAVETEXTURETOFILEWTYPE PD3DX11SaveTextureToFileW;
|
extern D3DX11SAVETEXTURETOFILEWTYPE PD3DX11SaveTextureToFileW;
|
||||||
|
|
||||||
#ifdef UNICODE
|
#ifdef UNICODE
|
||||||
#define PD3DX11SaveTextureToFile PD3DX11SaveTextureToFileW
|
#define PD3DX11SaveTextureToFile PD3DX11SaveTextureToFileW
|
||||||
#else
|
#else
|
||||||
#define PD3DX11SaveTextureToFile PD3DX11SaveTextureToFileA
|
#define PD3DX11SaveTextureToFile PD3DX11SaveTextureToFileA
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,68 +1,68 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
#include "DX11_D3DBlob.h"
|
#include "DX11_D3DBlob.h"
|
||||||
|
|
||||||
namespace DX11
|
namespace DX11
|
||||||
{
|
{
|
||||||
|
|
||||||
D3DBlob::D3DBlob(unsigned int blob_size, const u8* init_data) : ref(1), size(blob_size), blob(NULL)
|
D3DBlob::D3DBlob(unsigned int blob_size, const u8* init_data) : ref(1), size(blob_size), blob(NULL)
|
||||||
{
|
{
|
||||||
data = new u8[blob_size];
|
data = new u8[blob_size];
|
||||||
if (init_data) memcpy(data, init_data, size);
|
if (init_data) memcpy(data, init_data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
D3DBlob::D3DBlob(ID3D10Blob* d3dblob) : ref(1)
|
D3DBlob::D3DBlob(ID3D10Blob* d3dblob) : ref(1)
|
||||||
{
|
{
|
||||||
blob = d3dblob;
|
blob = d3dblob;
|
||||||
data = (u8*)blob->GetBufferPointer();
|
data = (u8*)blob->GetBufferPointer();
|
||||||
size = blob->GetBufferSize();
|
size = blob->GetBufferSize();
|
||||||
d3dblob->AddRef();
|
d3dblob->AddRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
D3DBlob::~D3DBlob()
|
D3DBlob::~D3DBlob()
|
||||||
{
|
{
|
||||||
if (blob) blob->Release();
|
if (blob) blob->Release();
|
||||||
else delete[] data;
|
else delete[] data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3DBlob::AddRef()
|
void D3DBlob::AddRef()
|
||||||
{
|
{
|
||||||
++ref;
|
++ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int D3DBlob::Release()
|
unsigned int D3DBlob::Release()
|
||||||
{
|
{
|
||||||
if (--ref == 0)
|
if (--ref == 0)
|
||||||
{
|
{
|
||||||
delete this;
|
delete this;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int D3DBlob::Size()
|
unsigned int D3DBlob::Size()
|
||||||
{
|
{
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8* D3DBlob::Data()
|
u8* D3DBlob::Data()
|
||||||
{
|
{
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,52 +1,52 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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
|
#pragma once
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include <d3d11.h>
|
#include <d3d11.h>
|
||||||
|
|
||||||
namespace DX11
|
namespace DX11
|
||||||
{
|
{
|
||||||
|
|
||||||
// use this class instead ID3D10Blob or ID3D11Blob whenever possible
|
// use this class instead ID3D10Blob or ID3D11Blob whenever possible
|
||||||
class D3DBlob
|
class D3DBlob
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// memory will be copied into an own buffer
|
// memory will be copied into an own buffer
|
||||||
D3DBlob(unsigned int blob_size, const u8* init_data = NULL);
|
D3DBlob(unsigned int blob_size, const u8* init_data = NULL);
|
||||||
|
|
||||||
// d3dblob will be AddRef'd
|
// d3dblob will be AddRef'd
|
||||||
D3DBlob(ID3D10Blob* d3dblob);
|
D3DBlob(ID3D10Blob* d3dblob);
|
||||||
|
|
||||||
void AddRef();
|
void AddRef();
|
||||||
unsigned int Release();
|
unsigned int Release();
|
||||||
|
|
||||||
unsigned int Size();
|
unsigned int Size();
|
||||||
u8* Data();
|
u8* Data();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
~D3DBlob();
|
~D3DBlob();
|
||||||
|
|
||||||
unsigned int ref;
|
unsigned int ref;
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
|
|
||||||
u8* data;
|
u8* data;
|
||||||
ID3D10Blob* blob;
|
ID3D10Blob* blob;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,150 +1,150 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
#include <d3dx11.h>
|
#include <d3dx11.h>
|
||||||
#include <d3dcompiler.h>
|
#include <d3dcompiler.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
#include "DX11_D3DShader.h"
|
#include "DX11_D3DShader.h"
|
||||||
|
|
||||||
namespace DX11
|
namespace DX11
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace D3D
|
namespace D3D
|
||||||
{
|
{
|
||||||
|
|
||||||
// bytecode->shader
|
// bytecode->shader
|
||||||
ID3D11VertexShader* CreateVertexShaderFromByteCode(void* bytecode, unsigned int len)
|
ID3D11VertexShader* CreateVertexShaderFromByteCode(void* bytecode, unsigned int len)
|
||||||
{
|
{
|
||||||
ID3D11VertexShader* v_shader;
|
ID3D11VertexShader* v_shader;
|
||||||
HRESULT hr = D3D::device->CreateVertexShader(bytecode, len, NULL, &v_shader);
|
HRESULT hr = D3D::device->CreateVertexShader(bytecode, len, NULL, &v_shader);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
PanicAlert("CreateVertexShaderFromByteCode failed from %p (size %d) at %s %d\n", bytecode, len, __FILE__, __LINE__);
|
PanicAlert("CreateVertexShaderFromByteCode failed from %p (size %d) at %s %d\n", bytecode, len, __FILE__, __LINE__);
|
||||||
v_shader = NULL;
|
v_shader = NULL;
|
||||||
}
|
}
|
||||||
return v_shader;
|
return v_shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
// code->bytecode
|
// code->bytecode
|
||||||
bool CompileVertexShader(const char* code, unsigned int len, D3DBlob** blob)
|
bool CompileVertexShader(const char* code, unsigned int len, D3DBlob** blob)
|
||||||
{
|
{
|
||||||
ID3D10Blob* shaderBuffer = NULL;
|
ID3D10Blob* shaderBuffer = NULL;
|
||||||
ID3D10Blob* errorBuffer = NULL;
|
ID3D10Blob* errorBuffer = NULL;
|
||||||
|
|
||||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||||
UINT flags = D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY|D3D10_SHADER_DEBUG|D3D10_SHADER_WARNINGS_ARE_ERRORS;
|
UINT flags = D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY|D3D10_SHADER_DEBUG|D3D10_SHADER_WARNINGS_ARE_ERRORS;
|
||||||
#else
|
#else
|
||||||
UINT flags = D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY|D3D10_SHADER_OPTIMIZATION_LEVEL3|D3D10_SHADER_SKIP_VALIDATION;
|
UINT flags = D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY|D3D10_SHADER_OPTIMIZATION_LEVEL3|D3D10_SHADER_SKIP_VALIDATION;
|
||||||
#endif
|
#endif
|
||||||
HRESULT hr = PD3DX11CompileFromMemory(code, len, NULL, NULL, NULL, "main", D3D::VertexShaderVersionString(),
|
HRESULT hr = PD3DX11CompileFromMemory(code, len, NULL, NULL, NULL, "main", D3D::VertexShaderVersionString(),
|
||||||
flags, 0, NULL, &shaderBuffer, &errorBuffer, NULL);
|
flags, 0, NULL, &shaderBuffer, &errorBuffer, NULL);
|
||||||
|
|
||||||
if (FAILED(hr) || errorBuffer)
|
if (FAILED(hr) || errorBuffer)
|
||||||
{
|
{
|
||||||
std::string msg = (char*)errorBuffer->GetBufferPointer();
|
std::string msg = (char*)errorBuffer->GetBufferPointer();
|
||||||
msg += "\n\n";
|
msg += "\n\n";
|
||||||
msg += code;
|
msg += code;
|
||||||
MessageBoxA(0, msg.c_str(), "Error compiling pixel shader", MB_ICONERROR);
|
MessageBoxA(0, msg.c_str(), "Error compiling pixel shader", MB_ICONERROR);
|
||||||
|
|
||||||
*blob = NULL;
|
*blob = NULL;
|
||||||
errorBuffer->Release();
|
errorBuffer->Release();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*blob = new D3DBlob(shaderBuffer);
|
*blob = new D3DBlob(shaderBuffer);
|
||||||
shaderBuffer->Release();
|
shaderBuffer->Release();
|
||||||
}
|
}
|
||||||
return SUCCEEDED(hr);
|
return SUCCEEDED(hr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// bytecode->shader
|
// bytecode->shader
|
||||||
ID3D11PixelShader* CreatePixelShaderFromByteCode(void* bytecode, unsigned int len)
|
ID3D11PixelShader* CreatePixelShaderFromByteCode(void* bytecode, unsigned int len)
|
||||||
{
|
{
|
||||||
ID3D11PixelShader* p_shader;
|
ID3D11PixelShader* p_shader;
|
||||||
HRESULT hr = D3D::device->CreatePixelShader(bytecode, len, NULL, &p_shader);
|
HRESULT hr = D3D::device->CreatePixelShader(bytecode, len, NULL, &p_shader);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
PanicAlert("CreatePixelShaderFromByteCode failed at %s %d\n", __FILE__, __LINE__);
|
PanicAlert("CreatePixelShaderFromByteCode failed at %s %d\n", __FILE__, __LINE__);
|
||||||
p_shader = NULL;
|
p_shader = NULL;
|
||||||
}
|
}
|
||||||
return p_shader;
|
return p_shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
// code->bytecode
|
// code->bytecode
|
||||||
bool CompilePixelShader(const char* code, unsigned int len, D3DBlob** blob)
|
bool CompilePixelShader(const char* code, unsigned int len, D3DBlob** blob)
|
||||||
{
|
{
|
||||||
ID3D10Blob* shaderBuffer = NULL;
|
ID3D10Blob* shaderBuffer = NULL;
|
||||||
ID3D10Blob* errorBuffer = NULL;
|
ID3D10Blob* errorBuffer = NULL;
|
||||||
|
|
||||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||||
UINT flags = D3D10_SHADER_DEBUG|D3D10_SHADER_WARNINGS_ARE_ERRORS;
|
UINT flags = D3D10_SHADER_DEBUG|D3D10_SHADER_WARNINGS_ARE_ERRORS;
|
||||||
#else
|
#else
|
||||||
UINT flags = D3D10_SHADER_OPTIMIZATION_LEVEL3;
|
UINT flags = D3D10_SHADER_OPTIMIZATION_LEVEL3;
|
||||||
#endif
|
#endif
|
||||||
HRESULT hr = PD3DX11CompileFromMemory(code, len, NULL, NULL, NULL, "main", D3D::PixelShaderVersionString(),
|
HRESULT hr = PD3DX11CompileFromMemory(code, len, NULL, NULL, NULL, "main", D3D::PixelShaderVersionString(),
|
||||||
flags, 0, NULL, &shaderBuffer, &errorBuffer, NULL);
|
flags, 0, NULL, &shaderBuffer, &errorBuffer, NULL);
|
||||||
|
|
||||||
if (FAILED(hr) || errorBuffer)
|
if (FAILED(hr) || errorBuffer)
|
||||||
{
|
{
|
||||||
std::string msg = (char*)errorBuffer->GetBufferPointer();
|
std::string msg = (char*)errorBuffer->GetBufferPointer();
|
||||||
msg += "\n\n";
|
msg += "\n\n";
|
||||||
msg += code;
|
msg += code;
|
||||||
MessageBoxA(0, msg.c_str(), "Error compiling pixel shader", MB_ICONERROR);
|
MessageBoxA(0, msg.c_str(), "Error compiling pixel shader", MB_ICONERROR);
|
||||||
|
|
||||||
*blob = NULL;
|
*blob = NULL;
|
||||||
errorBuffer->Release();
|
errorBuffer->Release();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*blob = new D3DBlob(shaderBuffer);
|
*blob = new D3DBlob(shaderBuffer);
|
||||||
shaderBuffer->Release();
|
shaderBuffer->Release();
|
||||||
}
|
}
|
||||||
return SUCCEEDED(hr);
|
return SUCCEEDED(hr);
|
||||||
}
|
}
|
||||||
|
|
||||||
ID3D11VertexShader* CompileAndCreateVertexShader(const char* code, unsigned int len)
|
ID3D11VertexShader* CompileAndCreateVertexShader(const char* code, unsigned int len)
|
||||||
{
|
{
|
||||||
D3DBlob* blob = NULL;
|
D3DBlob* blob = NULL;
|
||||||
if (CompileVertexShader(code, len, &blob))
|
if (CompileVertexShader(code, len, &blob))
|
||||||
{
|
{
|
||||||
ID3D11VertexShader* v_shader = CreateVertexShaderFromByteCode(blob);
|
ID3D11VertexShader* v_shader = CreateVertexShaderFromByteCode(blob);
|
||||||
blob->Release();
|
blob->Release();
|
||||||
return v_shader;
|
return v_shader;
|
||||||
}
|
}
|
||||||
PanicAlert("Failed to compile and create vertex shader from %p (size %d) at %s %d\n", code, len, __FILE__, __LINE__);
|
PanicAlert("Failed to compile and create vertex shader from %p (size %d) at %s %d\n", code, len, __FILE__, __LINE__);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ID3D11PixelShader* CompileAndCreatePixelShader(const char* code, unsigned int len)
|
ID3D11PixelShader* CompileAndCreatePixelShader(const char* code, unsigned int len)
|
||||||
{
|
{
|
||||||
D3DBlob* blob = NULL;
|
D3DBlob* blob = NULL;
|
||||||
CompilePixelShader(code, len, &blob);
|
CompilePixelShader(code, len, &blob);
|
||||||
if (blob)
|
if (blob)
|
||||||
{
|
{
|
||||||
ID3D11PixelShader* p_shader = CreatePixelShaderFromByteCode(blob);
|
ID3D11PixelShader* p_shader = CreatePixelShaderFromByteCode(blob);
|
||||||
blob->Release();
|
blob->Release();
|
||||||
return p_shader;
|
return p_shader;
|
||||||
}
|
}
|
||||||
PanicAlert("Failed to compile and create pixel shader, %s %d\n", __FILE__, __LINE__);
|
PanicAlert("Failed to compile and create pixel shader, %s %d\n", __FILE__, __LINE__);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,44 +1,44 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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
|
#pragma once
|
||||||
|
|
||||||
#include "DX11_D3DBase.h"
|
#include "DX11_D3DBase.h"
|
||||||
|
|
||||||
namespace DX11
|
namespace DX11
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace D3D
|
namespace D3D
|
||||||
{
|
{
|
||||||
ID3D11VertexShader* CreateVertexShaderFromByteCode(void* bytecode, unsigned int len);
|
ID3D11VertexShader* CreateVertexShaderFromByteCode(void* bytecode, unsigned int len);
|
||||||
ID3D11PixelShader* CreatePixelShaderFromByteCode(void* bytecode, unsigned int len);
|
ID3D11PixelShader* CreatePixelShaderFromByteCode(void* bytecode, unsigned int len);
|
||||||
|
|
||||||
// The returned bytecode buffers should be Release()d.
|
// The returned bytecode buffers should be Release()d.
|
||||||
bool CompileVertexShader(const char* code, unsigned int len, D3DBlob** blob);
|
bool CompileVertexShader(const char* code, unsigned int len, D3DBlob** blob);
|
||||||
bool CompilePixelShader(const char* code, unsigned int len, D3DBlob** blob);
|
bool CompilePixelShader(const char* code, unsigned int len, D3DBlob** blob);
|
||||||
|
|
||||||
// Utility functions
|
// Utility functions
|
||||||
ID3D11VertexShader* CompileAndCreateVertexShader(const char* code, unsigned int len);
|
ID3D11VertexShader* CompileAndCreateVertexShader(const char* code, unsigned int len);
|
||||||
ID3D11PixelShader* CompileAndCreatePixelShader(const char* code, unsigned int len);
|
ID3D11PixelShader* CompileAndCreatePixelShader(const char* code, unsigned int len);
|
||||||
|
|
||||||
inline ID3D11VertexShader* CreateVertexShaderFromByteCode(D3DBlob* bytecode) { return CreateVertexShaderFromByteCode(bytecode->Data(), bytecode->Size()); }
|
inline ID3D11VertexShader* CreateVertexShaderFromByteCode(D3DBlob* bytecode) { return CreateVertexShaderFromByteCode(bytecode->Data(), bytecode->Size()); }
|
||||||
inline ID3D11PixelShader* CreatePixelShaderFromByteCode(D3DBlob* bytecode) { return CreatePixelShaderFromByteCode(bytecode->Data(), bytecode->Size()); }
|
inline ID3D11PixelShader* CreatePixelShaderFromByteCode(D3DBlob* bytecode) { return CreatePixelShaderFromByteCode(bytecode->Data(), bytecode->Size()); }
|
||||||
inline ID3D11VertexShader* CompileAndCreateVertexShader(D3DBlob* code) { return CompileAndCreateVertexShader((const char*)code->Data(), code->Size()); }
|
inline ID3D11VertexShader* CompileAndCreateVertexShader(D3DBlob* code) { return CompileAndCreateVertexShader((const char*)code->Data(), code->Size()); }
|
||||||
inline ID3D11PixelShader* CompileAndCreatePixelShader(D3DBlob* code) { return CompileAndCreatePixelShader((const char*)code->Data(), code->Size()); }
|
inline ID3D11PixelShader* CompileAndCreatePixelShader(D3DBlob* code) { return CompileAndCreatePixelShader((const char*)code->Data(), code->Size()); }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,125 +1,125 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
#include <d3dx11.h>
|
#include <d3dx11.h>
|
||||||
#include "DX11_D3DBase.h"
|
#include "DX11_D3DBase.h"
|
||||||
#include "DX11_D3DTexture.h"
|
#include "DX11_D3DTexture.h"
|
||||||
|
|
||||||
namespace DX11
|
namespace DX11
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace D3D
|
namespace D3D
|
||||||
{
|
{
|
||||||
|
|
||||||
void ReplaceRGBATexture2D(ID3D11Texture2D* pTexture, const u8* buffer, unsigned int width, unsigned int height, unsigned int pitch, unsigned int level, D3D11_USAGE usage)
|
void ReplaceRGBATexture2D(ID3D11Texture2D* pTexture, const u8* buffer, unsigned int width, unsigned int height, unsigned int pitch, unsigned int level, D3D11_USAGE usage)
|
||||||
{
|
{
|
||||||
if (usage == D3D11_USAGE_DYNAMIC)
|
if (usage == D3D11_USAGE_DYNAMIC)
|
||||||
{
|
{
|
||||||
D3D11_MAPPED_SUBRESOURCE map;
|
D3D11_MAPPED_SUBRESOURCE map;
|
||||||
HRESULT hr = D3D::context->Map(pTexture, level, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
HRESULT hr = D3D::context->Map(pTexture, level, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
||||||
CHECK(SUCCEEDED(hr), "ID3D11DeviceContext::Map failed! (%x)", hr);
|
CHECK(SUCCEEDED(hr), "ID3D11DeviceContext::Map failed! (%x)", hr);
|
||||||
if (4 * pitch == map.RowPitch)
|
if (4 * pitch == map.RowPitch)
|
||||||
{
|
{
|
||||||
memcpy(map.pData, buffer, map.RowPitch * height);
|
memcpy(map.pData, buffer, map.RowPitch * height);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (unsigned int y = 0; y < height; ++y)
|
for (unsigned int y = 0; y < height; ++y)
|
||||||
memcpy((u8*)map.pData + y * map.RowPitch, (u32*)buffer + y * pitch, map.RowPitch);
|
memcpy((u8*)map.pData + y * map.RowPitch, (u32*)buffer + y * pitch, map.RowPitch);
|
||||||
}
|
}
|
||||||
D3D::context->Unmap(pTexture, level);
|
D3D::context->Unmap(pTexture, level);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
D3D11_BOX dest_region = CD3D11_BOX(0, 0, 0, width, height, 1);
|
D3D11_BOX dest_region = CD3D11_BOX(0, 0, 0, width, height, 1);
|
||||||
D3D::context->UpdateSubresource(pTexture, level, &dest_region, buffer, 4*pitch, 4*pitch*height);
|
D3D::context->UpdateSubresource(pTexture, level, &dest_region, buffer, 4*pitch, 4*pitch*height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
D3DTexture2D* D3DTexture2D::Create(unsigned int width, unsigned int height, D3D11_BIND_FLAG bind, D3D11_USAGE usage, DXGI_FORMAT fmt, unsigned int levels)
|
D3DTexture2D* D3DTexture2D::Create(unsigned int width, unsigned int height, D3D11_BIND_FLAG bind, D3D11_USAGE usage, DXGI_FORMAT fmt, unsigned int levels)
|
||||||
{
|
{
|
||||||
ID3D11Texture2D* pTexture = NULL;
|
ID3D11Texture2D* pTexture = NULL;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
D3D11_CPU_ACCESS_FLAG cpuflags;
|
D3D11_CPU_ACCESS_FLAG cpuflags;
|
||||||
if (usage == D3D11_USAGE_STAGING)
|
if (usage == D3D11_USAGE_STAGING)
|
||||||
cpuflags = (D3D11_CPU_ACCESS_FLAG)((int)D3D11_CPU_ACCESS_WRITE|(int)D3D11_CPU_ACCESS_READ);
|
cpuflags = (D3D11_CPU_ACCESS_FLAG)((int)D3D11_CPU_ACCESS_WRITE|(int)D3D11_CPU_ACCESS_READ);
|
||||||
else if (usage == D3D11_USAGE_DYNAMIC)
|
else if (usage == D3D11_USAGE_DYNAMIC)
|
||||||
cpuflags = D3D11_CPU_ACCESS_WRITE;
|
cpuflags = D3D11_CPU_ACCESS_WRITE;
|
||||||
else
|
else
|
||||||
cpuflags = (D3D11_CPU_ACCESS_FLAG)0;
|
cpuflags = (D3D11_CPU_ACCESS_FLAG)0;
|
||||||
|
|
||||||
D3D11_TEXTURE2D_DESC texdesc = CD3D11_TEXTURE2D_DESC(fmt, width, height, 1, levels, bind, usage, cpuflags);
|
D3D11_TEXTURE2D_DESC texdesc = CD3D11_TEXTURE2D_DESC(fmt, width, height, 1, levels, bind, usage, cpuflags);
|
||||||
hr = D3D::device->CreateTexture2D(&texdesc, NULL, &pTexture);
|
hr = D3D::device->CreateTexture2D(&texdesc, NULL, &pTexture);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
PanicAlert("Failed to create texture at %s, line %d: hr=%#x\n", __FILE__, __LINE__, hr);
|
PanicAlert("Failed to create texture at %s, line %d: hr=%#x\n", __FILE__, __LINE__, hr);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
D3DTexture2D* ret = new D3DTexture2D(pTexture, bind);
|
D3DTexture2D* ret = new D3DTexture2D(pTexture, bind);
|
||||||
SAFE_RELEASE(pTexture);
|
SAFE_RELEASE(pTexture);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3DTexture2D::AddRef()
|
void D3DTexture2D::AddRef()
|
||||||
{
|
{
|
||||||
++ref;
|
++ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT D3DTexture2D::Release()
|
UINT D3DTexture2D::Release()
|
||||||
{
|
{
|
||||||
--ref;
|
--ref;
|
||||||
if (ref == 0)
|
if (ref == 0)
|
||||||
{
|
{
|
||||||
delete this;
|
delete this;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
D3DTexture2D::D3DTexture2D(ID3D11Texture2D* texptr, D3D11_BIND_FLAG bind,
|
D3DTexture2D::D3DTexture2D(ID3D11Texture2D* texptr, D3D11_BIND_FLAG bind,
|
||||||
DXGI_FORMAT srv_format, DXGI_FORMAT dsv_format, DXGI_FORMAT rtv_format)
|
DXGI_FORMAT srv_format, DXGI_FORMAT dsv_format, DXGI_FORMAT rtv_format)
|
||||||
: ref(1), tex(texptr), srv(NULL), rtv(NULL), dsv(NULL)
|
: ref(1), tex(texptr), srv(NULL), rtv(NULL), dsv(NULL)
|
||||||
{
|
{
|
||||||
D3D11_SHADER_RESOURCE_VIEW_DESC srv_desc = CD3D11_SHADER_RESOURCE_VIEW_DESC(D3D11_SRV_DIMENSION_TEXTURE2D, srv_format);
|
D3D11_SHADER_RESOURCE_VIEW_DESC srv_desc = CD3D11_SHADER_RESOURCE_VIEW_DESC(D3D11_SRV_DIMENSION_TEXTURE2D, srv_format);
|
||||||
D3D11_DEPTH_STENCIL_VIEW_DESC dsv_desc = CD3D11_DEPTH_STENCIL_VIEW_DESC(D3D11_DSV_DIMENSION_TEXTURE2D, dsv_format);
|
D3D11_DEPTH_STENCIL_VIEW_DESC dsv_desc = CD3D11_DEPTH_STENCIL_VIEW_DESC(D3D11_DSV_DIMENSION_TEXTURE2D, dsv_format);
|
||||||
D3D11_RENDER_TARGET_VIEW_DESC rtv_desc = CD3D11_RENDER_TARGET_VIEW_DESC(D3D11_RTV_DIMENSION_TEXTURE2D, rtv_format);
|
D3D11_RENDER_TARGET_VIEW_DESC rtv_desc = CD3D11_RENDER_TARGET_VIEW_DESC(D3D11_RTV_DIMENSION_TEXTURE2D, rtv_format);
|
||||||
|
|
||||||
if (bind & D3D11_BIND_SHADER_RESOURCE)
|
if (bind & D3D11_BIND_SHADER_RESOURCE)
|
||||||
D3D::device->CreateShaderResourceView(tex, &srv_desc, &srv);
|
D3D::device->CreateShaderResourceView(tex, &srv_desc, &srv);
|
||||||
|
|
||||||
if (bind & D3D11_BIND_RENDER_TARGET)
|
if (bind & D3D11_BIND_RENDER_TARGET)
|
||||||
D3D::device->CreateRenderTargetView(tex, &rtv_desc, &rtv);
|
D3D::device->CreateRenderTargetView(tex, &rtv_desc, &rtv);
|
||||||
|
|
||||||
if (bind & D3D11_BIND_DEPTH_STENCIL)
|
if (bind & D3D11_BIND_DEPTH_STENCIL)
|
||||||
D3D::device->CreateDepthStencilView(tex, &dsv_desc, &dsv);
|
D3D::device->CreateDepthStencilView(tex, &dsv_desc, &dsv);
|
||||||
|
|
||||||
tex->AddRef();
|
tex->AddRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
D3DTexture2D::~D3DTexture2D()
|
D3DTexture2D::~D3DTexture2D()
|
||||||
{
|
{
|
||||||
SAFE_RELEASE(srv);
|
SAFE_RELEASE(srv);
|
||||||
SAFE_RELEASE(rtv);
|
SAFE_RELEASE(rtv);
|
||||||
SAFE_RELEASE(dsv);
|
SAFE_RELEASE(dsv);
|
||||||
SAFE_RELEASE(tex);
|
SAFE_RELEASE(tex);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,60 +1,60 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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
|
#pragma once
|
||||||
|
|
||||||
#include "DX11_D3DBase.h"
|
#include "DX11_D3DBase.h"
|
||||||
|
|
||||||
namespace DX11
|
namespace DX11
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace D3D
|
namespace D3D
|
||||||
{
|
{
|
||||||
void ReplaceRGBATexture2D(ID3D11Texture2D* pTexture, const u8* buffer, unsigned int width, unsigned int height, unsigned int pitch, unsigned int level, D3D11_USAGE usage);
|
void ReplaceRGBATexture2D(ID3D11Texture2D* pTexture, const u8* buffer, unsigned int width, unsigned int height, unsigned int pitch, unsigned int level, D3D11_USAGE usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
class D3DTexture2D
|
class D3DTexture2D
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// there are two ways to create a D3DTexture2D object:
|
// there are two ways to create a D3DTexture2D object:
|
||||||
// either create an ID3D11Texture2D object, pass it to the constructor and specify what views to create
|
// either create an ID3D11Texture2D object, pass it to the constructor and specify what views to create
|
||||||
// or let the texture automatically be created by D3DTexture2D::Create
|
// or let the texture automatically be created by D3DTexture2D::Create
|
||||||
|
|
||||||
D3DTexture2D(ID3D11Texture2D* texptr, D3D11_BIND_FLAG bind, DXGI_FORMAT srv_format = DXGI_FORMAT_UNKNOWN, DXGI_FORMAT dsv_format = DXGI_FORMAT_UNKNOWN, DXGI_FORMAT rtv_format = DXGI_FORMAT_UNKNOWN);
|
D3DTexture2D(ID3D11Texture2D* texptr, D3D11_BIND_FLAG bind, DXGI_FORMAT srv_format = DXGI_FORMAT_UNKNOWN, DXGI_FORMAT dsv_format = DXGI_FORMAT_UNKNOWN, DXGI_FORMAT rtv_format = DXGI_FORMAT_UNKNOWN);
|
||||||
static D3DTexture2D* Create(unsigned int width, unsigned int height, D3D11_BIND_FLAG bind, D3D11_USAGE usage, DXGI_FORMAT, unsigned int levels = 1);
|
static D3DTexture2D* Create(unsigned int width, unsigned int height, D3D11_BIND_FLAG bind, D3D11_USAGE usage, DXGI_FORMAT, unsigned int levels = 1);
|
||||||
|
|
||||||
// reference counting, use AddRef() when creating a new reference and Release() it when you don't need it anymore
|
// reference counting, use AddRef() when creating a new reference and Release() it when you don't need it anymore
|
||||||
void AddRef();
|
void AddRef();
|
||||||
UINT Release();
|
UINT Release();
|
||||||
|
|
||||||
ID3D11Texture2D* &GetTex() { return tex; }
|
ID3D11Texture2D* &GetTex() { return tex; }
|
||||||
ID3D11ShaderResourceView* &GetSRV() { return srv; }
|
ID3D11ShaderResourceView* &GetSRV() { return srv; }
|
||||||
ID3D11RenderTargetView* &GetRTV() { return rtv; }
|
ID3D11RenderTargetView* &GetRTV() { return rtv; }
|
||||||
ID3D11DepthStencilView* &GetDSV() { return dsv; }
|
ID3D11DepthStencilView* &GetDSV() { return dsv; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
~D3DTexture2D();
|
~D3DTexture2D();
|
||||||
|
|
||||||
ID3D11Texture2D* tex;
|
ID3D11Texture2D* tex;
|
||||||
ID3D11ShaderResourceView* srv;
|
ID3D11ShaderResourceView* srv;
|
||||||
ID3D11RenderTargetView* rtv;
|
ID3D11RenderTargetView* rtv;
|
||||||
ID3D11DepthStencilView* dsv;
|
ID3D11DepthStencilView* dsv;
|
||||||
D3D11_BIND_FLAG bindflags;
|
D3D11_BIND_FLAG bindflags;
|
||||||
UINT ref;
|
UINT ref;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,91 +1,91 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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
|
#pragma once
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <MathUtil.h>
|
#include <MathUtil.h>
|
||||||
|
|
||||||
#include "DX11_D3DBase.h"
|
#include "DX11_D3DBase.h"
|
||||||
|
|
||||||
namespace DX11
|
namespace DX11
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace D3D
|
namespace D3D
|
||||||
{
|
{
|
||||||
// Font creation flags
|
// Font creation flags
|
||||||
#define D3DFONT_BOLD 0x0001
|
#define D3DFONT_BOLD 0x0001
|
||||||
#define D3DFONT_ITALIC 0x0002
|
#define D3DFONT_ITALIC 0x0002
|
||||||
|
|
||||||
// Font rendering flags
|
// Font rendering flags
|
||||||
#define D3DFONT_CENTERED 0x0001
|
#define D3DFONT_CENTERED 0x0001
|
||||||
|
|
||||||
class CD3DFont
|
class CD3DFont
|
||||||
{
|
{
|
||||||
ID3D11ShaderResourceView* m_pTexture;
|
ID3D11ShaderResourceView* m_pTexture;
|
||||||
ID3D11Buffer* m_pVB;
|
ID3D11Buffer* m_pVB;
|
||||||
ID3D11InputLayout* m_InputLayout;
|
ID3D11InputLayout* m_InputLayout;
|
||||||
ID3D11PixelShader* m_pshader;
|
ID3D11PixelShader* m_pshader;
|
||||||
ID3D11VertexShader* m_vshader;
|
ID3D11VertexShader* m_vshader;
|
||||||
ID3D11BlendState* m_blendstate;
|
ID3D11BlendState* m_blendstate;
|
||||||
ID3D11RasterizerState* m_raststate;
|
ID3D11RasterizerState* m_raststate;
|
||||||
const int m_dwTexWidth;
|
const int m_dwTexWidth;
|
||||||
const int m_dwTexHeight;
|
const int m_dwTexHeight;
|
||||||
unsigned int m_LineHeight;
|
unsigned int m_LineHeight;
|
||||||
float m_fTexCoords[128-32][4];
|
float m_fTexCoords[128-32][4];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CD3DFont();
|
CD3DFont();
|
||||||
// 2D text drawing function
|
// 2D text drawing function
|
||||||
// Initializing and destroying device-dependent objects
|
// Initializing and destroying device-dependent objects
|
||||||
int Init();
|
int Init();
|
||||||
int Shutdown();
|
int Shutdown();
|
||||||
int DrawTextScaled(float x, float y,
|
int DrawTextScaled(float x, float y,
|
||||||
float size,
|
float size,
|
||||||
float spacing, u32 dwColor,
|
float spacing, u32 dwColor,
|
||||||
const char* strText, bool center=true);
|
const char* strText, bool center=true);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern CD3DFont font;
|
extern CD3DFont font;
|
||||||
|
|
||||||
void InitUtils();
|
void InitUtils();
|
||||||
void ShutdownUtils();
|
void ShutdownUtils();
|
||||||
|
|
||||||
void SetPointCopySampler();
|
void SetPointCopySampler();
|
||||||
void SetLinearCopySampler();
|
void SetLinearCopySampler();
|
||||||
|
|
||||||
void drawShadedTexQuad(ID3D11ShaderResourceView* texture,
|
void drawShadedTexQuad(ID3D11ShaderResourceView* texture,
|
||||||
const D3D11_RECT* rSource,
|
const D3D11_RECT* rSource,
|
||||||
int SourceWidth,
|
int SourceWidth,
|
||||||
int SourceHeight,
|
int SourceHeight,
|
||||||
ID3D11PixelShader* PShader,
|
ID3D11PixelShader* PShader,
|
||||||
ID3D11VertexShader* VShader,
|
ID3D11VertexShader* VShader,
|
||||||
ID3D11InputLayout* layout);
|
ID3D11InputLayout* layout);
|
||||||
void drawShadedTexSubQuad(ID3D11ShaderResourceView* texture,
|
void drawShadedTexSubQuad(ID3D11ShaderResourceView* texture,
|
||||||
const MathUtil::Rectangle<float>* rSource,
|
const MathUtil::Rectangle<float>* rSource,
|
||||||
int SourceWidth,
|
int SourceWidth,
|
||||||
int SourceHeight,
|
int SourceHeight,
|
||||||
const MathUtil::Rectangle<float>* rDest,
|
const MathUtil::Rectangle<float>* rDest,
|
||||||
ID3D11PixelShader* PShader,
|
ID3D11PixelShader* PShader,
|
||||||
ID3D11VertexShader* Vshader,
|
ID3D11VertexShader* Vshader,
|
||||||
ID3D11InputLayout* layout);
|
ID3D11InputLayout* layout);
|
||||||
void drawClearQuad(u32 Color, float z, ID3D11PixelShader* PShader, ID3D11VertexShader* Vshader, ID3D11InputLayout* layout);
|
void drawClearQuad(u32 Color, float z, ID3D11PixelShader* PShader, ID3D11VertexShader* Vshader, ID3D11InputLayout* layout);
|
||||||
void SaveRenderStates();
|
void SaveRenderStates();
|
||||||
void RestoreRenderStates();
|
void RestoreRenderStates();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,162 +1,162 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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/
|
||||||
|
|
||||||
// VideoCommon
|
// VideoCommon
|
||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
|
|
||||||
// DX11
|
// DX11
|
||||||
#include "DX11_Render.h"
|
#include "DX11_Render.h"
|
||||||
#include "DX11_D3DBase.h"
|
#include "DX11_D3DBase.h"
|
||||||
#include "DX11_D3DTexture.h"
|
#include "DX11_D3DTexture.h"
|
||||||
#include "DX11_D3DUtil.h"
|
#include "DX11_D3DUtil.h"
|
||||||
#include "DX11_FramebufferManager.h"
|
#include "DX11_FramebufferManager.h"
|
||||||
#include "DX11_PixelShaderCache.h"
|
#include "DX11_PixelShaderCache.h"
|
||||||
#include "DX11_VertexShaderCache.h"
|
#include "DX11_VertexShaderCache.h"
|
||||||
|
|
||||||
#include "../Main.h"
|
#include "../Main.h"
|
||||||
|
|
||||||
namespace DX11
|
namespace DX11
|
||||||
{
|
{
|
||||||
|
|
||||||
XFBSource FramebufferManager::m_realXFBSource; // used in real XFB mode
|
XFBSource FramebufferManager::m_realXFBSource; // used in real XFB mode
|
||||||
|
|
||||||
FramebufferManager::EFB FramebufferManager::m_efb;
|
FramebufferManager::EFB FramebufferManager::m_efb;
|
||||||
|
|
||||||
D3DTexture2D* &FramebufferManager::GetEFBColorTexture() { return m_efb.color_tex; }
|
D3DTexture2D* &FramebufferManager::GetEFBColorTexture() { return m_efb.color_tex; }
|
||||||
ID3D11Texture2D* &FramebufferManager::GetEFBColorStagingBuffer() { return m_efb.color_staging_buf; }
|
ID3D11Texture2D* &FramebufferManager::GetEFBColorStagingBuffer() { return m_efb.color_staging_buf; }
|
||||||
|
|
||||||
D3DTexture2D* &FramebufferManager::GetEFBDepthTexture() { return m_efb.depth_tex; }
|
D3DTexture2D* &FramebufferManager::GetEFBDepthTexture() { return m_efb.depth_tex; }
|
||||||
D3DTexture2D* &FramebufferManager::GetEFBDepthReadTexture() { return m_efb.depth_read_texture; }
|
D3DTexture2D* &FramebufferManager::GetEFBDepthReadTexture() { return m_efb.depth_read_texture; }
|
||||||
ID3D11Texture2D* &FramebufferManager::GetEFBDepthStagingBuffer() { return m_efb.depth_staging_buf; }
|
ID3D11Texture2D* &FramebufferManager::GetEFBDepthStagingBuffer() { return m_efb.depth_staging_buf; }
|
||||||
|
|
||||||
FramebufferManager::FramebufferManager()
|
FramebufferManager::FramebufferManager()
|
||||||
{
|
{
|
||||||
m_efb.color_tex = NULL;
|
m_efb.color_tex = NULL;
|
||||||
m_efb.color_staging_buf = NULL;
|
m_efb.color_staging_buf = NULL;
|
||||||
m_efb.depth_tex = NULL;
|
m_efb.depth_tex = NULL;
|
||||||
m_efb.depth_staging_buf = NULL;
|
m_efb.depth_staging_buf = NULL;
|
||||||
m_efb.depth_read_texture = NULL;
|
m_efb.depth_read_texture = NULL;
|
||||||
|
|
||||||
m_realXFBSource.tex = NULL;
|
m_realXFBSource.tex = NULL;
|
||||||
|
|
||||||
unsigned int target_width = Renderer::GetFullTargetWidth();
|
unsigned int target_width = Renderer::GetFullTargetWidth();
|
||||||
unsigned int target_height = Renderer::GetFullTargetHeight();
|
unsigned int target_height = Renderer::GetFullTargetHeight();
|
||||||
ID3D11Texture2D* buf;
|
ID3D11Texture2D* buf;
|
||||||
D3D11_TEXTURE2D_DESC texdesc;
|
D3D11_TEXTURE2D_DESC texdesc;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
// create framebuffer color texture
|
// create framebuffer color texture
|
||||||
m_efb.color_tex = D3DTexture2D::Create(target_width, target_height,
|
m_efb.color_tex = D3DTexture2D::Create(target_width, target_height,
|
||||||
(D3D11_BIND_FLAG)(D3D11_BIND_RENDER_TARGET|D3D11_BIND_SHADER_RESOURCE),
|
(D3D11_BIND_FLAG)(D3D11_BIND_RENDER_TARGET|D3D11_BIND_SHADER_RESOURCE),
|
||||||
D3D11_USAGE_DEFAULT, DXGI_FORMAT_R8G8B8A8_UNORM);
|
D3D11_USAGE_DEFAULT, DXGI_FORMAT_R8G8B8A8_UNORM);
|
||||||
CHECK(m_efb.color_tex, "create EFB color texture (size: %dx%d)", target_width, target_height);
|
CHECK(m_efb.color_tex, "create EFB color texture (size: %dx%d)", target_width, target_height);
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_tex->GetTex(), "EFB color texture");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_tex->GetTex(), "EFB color texture");
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_tex->GetRTV(), "EFB color texture render target view");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_tex->GetRTV(), "EFB color texture render target view");
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_tex->GetSRV(), "EFB color texture shader resource view");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_tex->GetSRV(), "EFB color texture shader resource view");
|
||||||
|
|
||||||
// create a staging texture for Renderer::AccessEFB
|
// create a staging texture for Renderer::AccessEFB
|
||||||
texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, 1, 1, 1, 1, 0,
|
texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, 1, 1, 1, 1, 0,
|
||||||
D3D11_USAGE_STAGING, D3D11_CPU_ACCESS_WRITE|D3D11_CPU_ACCESS_READ);
|
D3D11_USAGE_STAGING, D3D11_CPU_ACCESS_WRITE|D3D11_CPU_ACCESS_READ);
|
||||||
hr = D3D::device->CreateTexture2D(&texdesc, NULL, &m_efb.color_staging_buf);
|
hr = D3D::device->CreateTexture2D(&texdesc, NULL, &m_efb.color_staging_buf);
|
||||||
CHECK(SUCCEEDED(hr), "create EFB color staging buffer (hr=%#x)", hr);
|
CHECK(SUCCEEDED(hr), "create EFB color staging buffer (hr=%#x)", hr);
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_staging_buf, "EFB color staging texture (used for Renderer::AccessEFB)");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_staging_buf, "EFB color staging texture (used for Renderer::AccessEFB)");
|
||||||
|
|
||||||
// EFB depth buffer
|
// EFB depth buffer
|
||||||
texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R24G8_TYPELESS, target_width,
|
texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R24G8_TYPELESS, target_width,
|
||||||
target_height, 1, 1, D3D11_BIND_DEPTH_STENCIL|D3D11_BIND_SHADER_RESOURCE);
|
target_height, 1, 1, D3D11_BIND_DEPTH_STENCIL|D3D11_BIND_SHADER_RESOURCE);
|
||||||
hr = D3D::device->CreateTexture2D(&texdesc, NULL, &buf);
|
hr = D3D::device->CreateTexture2D(&texdesc, NULL, &buf);
|
||||||
CHECK(hr==S_OK, "create EFB depth texture (size: %dx%d; hr=%#x)", target_width, target_height, hr);
|
CHECK(hr==S_OK, "create EFB depth texture (size: %dx%d; hr=%#x)", target_width, target_height, hr);
|
||||||
m_efb.depth_tex = new D3DTexture2D(buf, (D3D11_BIND_FLAG)(D3D11_BIND_DEPTH_STENCIL|D3D11_BIND_SHADER_RESOURCE),
|
m_efb.depth_tex = new D3DTexture2D(buf, (D3D11_BIND_FLAG)(D3D11_BIND_DEPTH_STENCIL|D3D11_BIND_SHADER_RESOURCE),
|
||||||
DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_D24_UNORM_S8_UINT);
|
DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_D24_UNORM_S8_UINT);
|
||||||
SAFE_RELEASE(buf);
|
SAFE_RELEASE(buf);
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.depth_tex->GetTex(), "EFB depth texture");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.depth_tex->GetTex(), "EFB depth texture");
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.depth_tex->GetDSV(), "EFB depth texture depth stencil view");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.depth_tex->GetDSV(), "EFB depth texture depth stencil view");
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.depth_tex->GetSRV(), "EFB depth texture shader resource view");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.depth_tex->GetSRV(), "EFB depth texture shader resource view");
|
||||||
|
|
||||||
// render target for depth buffer access in Renderer::AccessEFB
|
// render target for depth buffer access in Renderer::AccessEFB
|
||||||
texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R32_FLOAT, 4, 4, 1, 1, D3D11_BIND_RENDER_TARGET);
|
texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R32_FLOAT, 4, 4, 1, 1, D3D11_BIND_RENDER_TARGET);
|
||||||
hr = D3D::device->CreateTexture2D(&texdesc, NULL, &buf);
|
hr = D3D::device->CreateTexture2D(&texdesc, NULL, &buf);
|
||||||
CHECK(hr==S_OK, "create EFB depth read texture (hr=%#x)", hr);
|
CHECK(hr==S_OK, "create EFB depth read texture (hr=%#x)", hr);
|
||||||
m_efb.depth_read_texture = new D3DTexture2D(buf, D3D11_BIND_RENDER_TARGET);
|
m_efb.depth_read_texture = new D3DTexture2D(buf, D3D11_BIND_RENDER_TARGET);
|
||||||
SAFE_RELEASE(buf);
|
SAFE_RELEASE(buf);
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.depth_read_texture->GetTex(), "EFB depth read texture (used in Renderer::AccessEFB)");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.depth_read_texture->GetTex(), "EFB depth read texture (used in Renderer::AccessEFB)");
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.depth_read_texture->GetRTV(), "EFB depth read texture render target view (used in Renderer::AccessEFB)");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.depth_read_texture->GetRTV(), "EFB depth read texture render target view (used in Renderer::AccessEFB)");
|
||||||
|
|
||||||
// staging texture to which we copy the data from m_efb.depth_read_texture
|
// staging texture to which we copy the data from m_efb.depth_read_texture
|
||||||
texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R32_FLOAT, 4, 4, 1, 1, 0, D3D11_USAGE_STAGING, D3D11_CPU_ACCESS_READ|D3D11_CPU_ACCESS_WRITE);
|
texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R32_FLOAT, 4, 4, 1, 1, 0, D3D11_USAGE_STAGING, D3D11_CPU_ACCESS_READ|D3D11_CPU_ACCESS_WRITE);
|
||||||
hr = D3D::device->CreateTexture2D(&texdesc, NULL, &m_efb.depth_staging_buf);
|
hr = D3D::device->CreateTexture2D(&texdesc, NULL, &m_efb.depth_staging_buf);
|
||||||
CHECK(hr==S_OK, "create EFB depth staging buffer (hr=%#x)", hr);
|
CHECK(hr==S_OK, "create EFB depth staging buffer (hr=%#x)", hr);
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.depth_staging_buf, "EFB depth staging texture (used for Renderer::AccessEFB)");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.depth_staging_buf, "EFB depth staging texture (used for Renderer::AccessEFB)");
|
||||||
}
|
}
|
||||||
|
|
||||||
FramebufferManager::~FramebufferManager()
|
FramebufferManager::~FramebufferManager()
|
||||||
{
|
{
|
||||||
SAFE_RELEASE(m_efb.color_tex);
|
SAFE_RELEASE(m_efb.color_tex);
|
||||||
SAFE_RELEASE(m_efb.color_staging_buf);
|
SAFE_RELEASE(m_efb.color_staging_buf);
|
||||||
SAFE_RELEASE(m_efb.depth_tex);
|
SAFE_RELEASE(m_efb.depth_tex);
|
||||||
SAFE_RELEASE(m_efb.depth_staging_buf);
|
SAFE_RELEASE(m_efb.depth_staging_buf);
|
||||||
SAFE_RELEASE(m_efb.depth_read_texture);
|
SAFE_RELEASE(m_efb.depth_read_texture);
|
||||||
|
|
||||||
SAFE_RELEASE(m_realXFBSource.tex);
|
SAFE_RELEASE(m_realXFBSource.tex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void XFBSource::CopyEFB(const TargetRectangle& efbSource)
|
void XFBSource::CopyEFB(const TargetRectangle& efbSource)
|
||||||
{
|
{
|
||||||
// copy EFB data to XFB and restore render target again
|
// copy EFB data to XFB and restore render target again
|
||||||
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)texWidth, (float)texHeight);
|
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)texWidth, (float)texHeight);
|
||||||
D3D::context->RSSetViewports(1, &vp);
|
D3D::context->RSSetViewports(1, &vp);
|
||||||
D3D::context->OMSetRenderTargets(1, &tex->GetRTV(), NULL);
|
D3D::context->OMSetRenderTargets(1, &tex->GetRTV(), NULL);
|
||||||
D3D::SetLinearCopySampler();
|
D3D::SetLinearCopySampler();
|
||||||
|
|
||||||
D3DTexture2D* const ctex = FramebufferManager::GetEFBColorTexture();
|
D3DTexture2D* const ctex = FramebufferManager::GetEFBColorTexture();
|
||||||
|
|
||||||
D3D::drawShadedTexQuad(ctex->GetSRV(), efbSource.AsRECT(),
|
D3D::drawShadedTexQuad(ctex->GetSRV(), efbSource.AsRECT(),
|
||||||
Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight(),
|
Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight(),
|
||||||
PixelShaderCache::GetColorCopyProgram(), VertexShaderCache::GetSimpleVertexShader(),
|
PixelShaderCache::GetColorCopyProgram(), VertexShaderCache::GetSimpleVertexShader(),
|
||||||
VertexShaderCache::GetSimpleInputLayout());
|
VertexShaderCache::GetSimpleInputLayout());
|
||||||
|
|
||||||
D3D::context->OMSetRenderTargets(1, &ctex->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV());
|
D3D::context->OMSetRenderTargets(1, &ctex->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV());
|
||||||
}
|
}
|
||||||
|
|
||||||
XFBSource::~XFBSource()
|
XFBSource::~XFBSource()
|
||||||
{
|
{
|
||||||
tex->Release();
|
tex->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
XFBSourceBase* FramebufferManager::CreateXFBSource(unsigned int target_width, unsigned int target_height)
|
XFBSourceBase* FramebufferManager::CreateXFBSource(unsigned int target_width, unsigned int target_height)
|
||||||
{
|
{
|
||||||
XFBSource* const xfbs = new XFBSource;
|
XFBSource* const xfbs = new XFBSource;
|
||||||
xfbs->tex = D3DTexture2D::Create(target_width, target_height,
|
xfbs->tex = D3DTexture2D::Create(target_width, target_height,
|
||||||
(D3D11_BIND_FLAG)(D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE),
|
(D3D11_BIND_FLAG)(D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE),
|
||||||
D3D11_USAGE_DEFAULT, DXGI_FORMAT_R8G8B8A8_UNORM);
|
D3D11_USAGE_DEFAULT, DXGI_FORMAT_R8G8B8A8_UNORM);
|
||||||
|
|
||||||
return xfbs;
|
return xfbs;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramebufferManager::copyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
|
void FramebufferManager::copyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
PanicAlert("copyToRealXFB not implemented, yet\n");
|
PanicAlert("copyToRealXFB not implemented, yet\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
const XFBSource** FramebufferManager::getRealXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount)
|
const XFBSource** FramebufferManager::getRealXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount)
|
||||||
{
|
{
|
||||||
PanicAlert("getRealXFBSource not implemented, yet\n");
|
PanicAlert("getRealXFBSource not implemented, yet\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,108 +1,108 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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/
|
||||||
|
|
||||||
#ifndef _DX11_FBMANAGER_D3D_H_
|
#ifndef _DX11_FBMANAGER_D3D_H_
|
||||||
#define _DX11_FBMANAGER_D3D_H_
|
#define _DX11_FBMANAGER_D3D_H_
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
#include "DX11_D3DBase.h"
|
#include "DX11_D3DBase.h"
|
||||||
|
|
||||||
#include "../FramebufferManager.h"
|
#include "../FramebufferManager.h"
|
||||||
|
|
||||||
namespace DX11
|
namespace DX11
|
||||||
{
|
{
|
||||||
|
|
||||||
// On the GameCube, the game sends a request for the graphics processor to
|
// On the GameCube, the game sends a request for the graphics processor to
|
||||||
// transfer its internal EFB (Embedded Framebuffer) to an area in GameCube RAM
|
// transfer its internal EFB (Embedded Framebuffer) to an area in GameCube RAM
|
||||||
// called the XFB (External Framebuffer). The size and location of the XFB is
|
// called the XFB (External Framebuffer). The size and location of the XFB is
|
||||||
// decided at the time of the copy, and the format is always YUYV. The video
|
// decided at the time of the copy, and the format is always YUYV. The video
|
||||||
// interface is given a pointer to the XFB, which will be decoded and
|
// interface is given a pointer to the XFB, which will be decoded and
|
||||||
// displayed on the TV.
|
// displayed on the TV.
|
||||||
//
|
//
|
||||||
// There are two ways for Dolphin to emulate this:
|
// There are two ways for Dolphin to emulate this:
|
||||||
//
|
//
|
||||||
// Real XFB mode:
|
// Real XFB mode:
|
||||||
//
|
//
|
||||||
// Dolphin will behave like the GameCube and encode the EFB to
|
// Dolphin will behave like the GameCube and encode the EFB to
|
||||||
// a portion of GameCube RAM. The emulated video interface will decode the data
|
// a portion of GameCube RAM. The emulated video interface will decode the data
|
||||||
// for output to the screen.
|
// for output to the screen.
|
||||||
//
|
//
|
||||||
// Advantages: Behaves exactly like the GameCube.
|
// Advantages: Behaves exactly like the GameCube.
|
||||||
// Disadvantages: Resolution will be limited.
|
// Disadvantages: Resolution will be limited.
|
||||||
//
|
//
|
||||||
// Virtual XFB mode:
|
// Virtual XFB mode:
|
||||||
//
|
//
|
||||||
// When a request is made to copy the EFB to an XFB, Dolphin
|
// When a request is made to copy the EFB to an XFB, Dolphin
|
||||||
// will remember the RAM location and size of the XFB in a Virtual XFB list.
|
// will remember the RAM location and size of the XFB in a Virtual XFB list.
|
||||||
// The video interface will look up the XFB in the list and use the enhanced
|
// The video interface will look up the XFB in the list and use the enhanced
|
||||||
// data stored there, if available.
|
// data stored there, if available.
|
||||||
//
|
//
|
||||||
// Advantages: Enables high resolution graphics, better than real hardware.
|
// Advantages: Enables high resolution graphics, better than real hardware.
|
||||||
// Disadvantages: If the GameCube CPU writes directly to the XFB (which is
|
// Disadvantages: If the GameCube CPU writes directly to the XFB (which is
|
||||||
// possible but uncommon), the Virtual XFB will not capture this information.
|
// possible but uncommon), the Virtual XFB will not capture this information.
|
||||||
|
|
||||||
// There may be multiple XFBs in GameCube RAM. This is the maximum number to
|
// There may be multiple XFBs in GameCube RAM. This is the maximum number to
|
||||||
// virtualize.
|
// virtualize.
|
||||||
|
|
||||||
struct XFBSource : public XFBSourceBase
|
struct XFBSource : public XFBSourceBase
|
||||||
{
|
{
|
||||||
XFBSource() : tex(NULL) {}
|
XFBSource() : tex(NULL) {}
|
||||||
~XFBSource();
|
~XFBSource();
|
||||||
|
|
||||||
void CopyEFB(const TargetRectangle& efbSource);
|
void CopyEFB(const TargetRectangle& efbSource);
|
||||||
|
|
||||||
D3DTexture2D* tex;
|
D3DTexture2D* tex;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FramebufferManager : public ::FramebufferManagerBase
|
class FramebufferManager : public ::FramebufferManagerBase
|
||||||
{
|
{
|
||||||
friend struct XFBSource;
|
friend struct XFBSource;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FramebufferManager();
|
FramebufferManager();
|
||||||
~FramebufferManager();
|
~FramebufferManager();
|
||||||
|
|
||||||
static D3DTexture2D* &GetEFBColorTexture();
|
static D3DTexture2D* &GetEFBColorTexture();
|
||||||
static ID3D11Texture2D* &GetEFBColorStagingBuffer();
|
static ID3D11Texture2D* &GetEFBColorStagingBuffer();
|
||||||
|
|
||||||
static D3DTexture2D* &GetEFBDepthTexture();
|
static D3DTexture2D* &GetEFBDepthTexture();
|
||||||
static D3DTexture2D* &GetEFBDepthReadTexture();
|
static D3DTexture2D* &GetEFBDepthReadTexture();
|
||||||
static ID3D11Texture2D* &GetEFBDepthStagingBuffer();
|
static ID3D11Texture2D* &GetEFBDepthStagingBuffer();
|
||||||
|
|
||||||
XFBSourceBase* CreateXFBSource(unsigned int target_width, unsigned int target_height);
|
XFBSourceBase* CreateXFBSource(unsigned int target_width, unsigned int target_height);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void copyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc);
|
static void copyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc);
|
||||||
static const XFBSource** getRealXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount);
|
static const XFBSource** getRealXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount);
|
||||||
|
|
||||||
static XFBSource m_realXFBSource; // used in real XFB mode
|
static XFBSource m_realXFBSource; // used in real XFB mode
|
||||||
|
|
||||||
static struct EFB
|
static struct EFB
|
||||||
{
|
{
|
||||||
D3DTexture2D* color_tex;
|
D3DTexture2D* color_tex;
|
||||||
ID3D11Texture2D* color_staging_buf;
|
ID3D11Texture2D* color_staging_buf;
|
||||||
|
|
||||||
D3DTexture2D* depth_tex;
|
D3DTexture2D* depth_tex;
|
||||||
ID3D11Texture2D* depth_staging_buf;
|
ID3D11Texture2D* depth_staging_buf;
|
||||||
D3DTexture2D* depth_read_texture;
|
D3DTexture2D* depth_read_texture;
|
||||||
} m_efb;
|
} m_efb;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,372 +1,372 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
#include "DX11_GfxState.h"
|
#include "DX11_GfxState.h"
|
||||||
|
|
||||||
namespace DX11
|
namespace DX11
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace D3D
|
namespace D3D
|
||||||
{
|
{
|
||||||
|
|
||||||
EmuGfxState* gfxstate;
|
EmuGfxState* gfxstate;
|
||||||
StateManager* stateman;
|
StateManager* stateman;
|
||||||
|
|
||||||
EmuGfxState::EmuGfxState() : vertexshader(NULL), vsbytecode(NULL), pixelshader(NULL), psbytecode(NULL), apply_called(false)
|
EmuGfxState::EmuGfxState() : vertexshader(NULL), vsbytecode(NULL), pixelshader(NULL), psbytecode(NULL), apply_called(false)
|
||||||
{
|
{
|
||||||
for (unsigned int k = 0;k < 8;k++)
|
for (unsigned int k = 0;k < 8;k++)
|
||||||
{
|
{
|
||||||
float border[4] = {0.f, 0.f, 0.f, 0.f};
|
float border[4] = {0.f, 0.f, 0.f, 0.f};
|
||||||
shader_resources[k] = NULL;
|
shader_resources[k] = NULL;
|
||||||
samplerdesc[k] = CD3D11_SAMPLER_DESC(D3D11_FILTER_MIN_MAG_MIP_LINEAR, D3D11_TEXTURE_ADDRESS_CLAMP, D3D11_TEXTURE_ADDRESS_CLAMP, D3D11_TEXTURE_ADDRESS_CLAMP, 0.f, 16, D3D11_COMPARISON_ALWAYS, border, -D3D11_FLOAT32_MAX, D3D11_FLOAT32_MAX);
|
samplerdesc[k] = CD3D11_SAMPLER_DESC(D3D11_FILTER_MIN_MAG_MIP_LINEAR, D3D11_TEXTURE_ADDRESS_CLAMP, D3D11_TEXTURE_ADDRESS_CLAMP, D3D11_TEXTURE_ADDRESS_CLAMP, 0.f, 16, D3D11_COMPARISON_ALWAYS, border, -D3D11_FLOAT32_MAX, D3D11_FLOAT32_MAX);
|
||||||
if(g_ActiveConfig.iMaxAnisotropy > 1) samplerdesc[k].Filter = D3D11_FILTER_ANISOTROPIC;
|
if(g_ActiveConfig.iMaxAnisotropy > 1) samplerdesc[k].Filter = D3D11_FILTER_ANISOTROPIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&blenddesc, 0, sizeof(blenddesc));
|
memset(&blenddesc, 0, sizeof(blenddesc));
|
||||||
blenddesc.AlphaToCoverageEnable = FALSE;
|
blenddesc.AlphaToCoverageEnable = FALSE;
|
||||||
blenddesc.IndependentBlendEnable = FALSE;
|
blenddesc.IndependentBlendEnable = FALSE;
|
||||||
blenddesc.RenderTarget[0].BlendEnable = FALSE;
|
blenddesc.RenderTarget[0].BlendEnable = FALSE;
|
||||||
blenddesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
|
blenddesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
|
||||||
blenddesc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE;
|
blenddesc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE;
|
||||||
blenddesc.RenderTarget[0].DestBlend = D3D11_BLEND_ZERO;
|
blenddesc.RenderTarget[0].DestBlend = D3D11_BLEND_ZERO;
|
||||||
blenddesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
|
blenddesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
|
||||||
blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
|
blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
|
||||||
blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
|
blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
|
||||||
blenddesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
|
blenddesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
|
||||||
|
|
||||||
memset(&depthdesc, 0, sizeof(depthdesc));
|
memset(&depthdesc, 0, sizeof(depthdesc));
|
||||||
depthdesc.DepthEnable = TRUE;
|
depthdesc.DepthEnable = TRUE;
|
||||||
depthdesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
|
depthdesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
|
||||||
depthdesc.DepthFunc = D3D11_COMPARISON_LESS;
|
depthdesc.DepthFunc = D3D11_COMPARISON_LESS;
|
||||||
depthdesc.StencilEnable = FALSE;
|
depthdesc.StencilEnable = FALSE;
|
||||||
depthdesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK;
|
depthdesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK;
|
||||||
depthdesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;
|
depthdesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;
|
||||||
|
|
||||||
// this probably must be changed once multisampling support gets added
|
// this probably must be changed once multisampling support gets added
|
||||||
rastdesc = CD3D11_RASTERIZER_DESC(D3D11_FILL_SOLID, D3D11_CULL_NONE, false, 0, 0.f, 0, false, true, false, false);
|
rastdesc = CD3D11_RASTERIZER_DESC(D3D11_FILL_SOLID, D3D11_CULL_NONE, false, 0, 0.f, 0, false, true, false, false);
|
||||||
|
|
||||||
pscbuf = NULL;
|
pscbuf = NULL;
|
||||||
vscbuf = NULL;
|
vscbuf = NULL;
|
||||||
vshaderchanged = false;
|
vshaderchanged = false;
|
||||||
inp_layout = NULL;
|
inp_layout = NULL;
|
||||||
num_inp_elems = 0;
|
num_inp_elems = 0;
|
||||||
|
|
||||||
pscbufchanged = false;
|
pscbufchanged = false;
|
||||||
vscbufchanged = false;
|
vscbufchanged = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
EmuGfxState::~EmuGfxState()
|
EmuGfxState::~EmuGfxState()
|
||||||
{
|
{
|
||||||
for (unsigned int k = 0;k < 8;k++)
|
for (unsigned int k = 0;k < 8;k++)
|
||||||
SAFE_RELEASE(shader_resources[k])
|
SAFE_RELEASE(shader_resources[k])
|
||||||
|
|
||||||
SAFE_RELEASE(vsbytecode);
|
SAFE_RELEASE(vsbytecode);
|
||||||
SAFE_RELEASE(psbytecode);
|
SAFE_RELEASE(psbytecode);
|
||||||
SAFE_RELEASE(vertexshader);
|
SAFE_RELEASE(vertexshader);
|
||||||
SAFE_RELEASE(pixelshader);
|
SAFE_RELEASE(pixelshader);
|
||||||
|
|
||||||
SAFE_RELEASE(pscbuf);
|
SAFE_RELEASE(pscbuf);
|
||||||
SAFE_RELEASE(vscbuf);
|
SAFE_RELEASE(vscbuf);
|
||||||
|
|
||||||
SAFE_RELEASE(inp_layout);
|
SAFE_RELEASE(inp_layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: No need to store the whole bytecode, signature might be enough (?)
|
// TODO: No need to store the whole bytecode, signature might be enough (?)
|
||||||
void EmuGfxState::SetVShader(ID3D11VertexShader* shader, D3DBlob* bcode)
|
void EmuGfxState::SetVShader(ID3D11VertexShader* shader, D3DBlob* bcode)
|
||||||
{
|
{
|
||||||
// TODO: vshaderchanged actually just needs to be true if the signature changed
|
// TODO: vshaderchanged actually just needs to be true if the signature changed
|
||||||
if (bcode && vsbytecode != bcode) vshaderchanged = true;
|
if (bcode && vsbytecode != bcode) vshaderchanged = true;
|
||||||
SAFE_RELEASE(vsbytecode);
|
SAFE_RELEASE(vsbytecode);
|
||||||
SAFE_RELEASE(vertexshader);
|
SAFE_RELEASE(vertexshader);
|
||||||
|
|
||||||
if (shader && bcode)
|
if (shader && bcode)
|
||||||
{
|
{
|
||||||
vertexshader = shader;
|
vertexshader = shader;
|
||||||
shader->AddRef();
|
shader->AddRef();
|
||||||
vsbytecode = bcode;
|
vsbytecode = bcode;
|
||||||
bcode->AddRef();
|
bcode->AddRef();
|
||||||
}
|
}
|
||||||
else if (shader || bcode)
|
else if (shader || bcode)
|
||||||
{
|
{
|
||||||
PanicAlert("Invalid parameters!\n");
|
PanicAlert("Invalid parameters!\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuGfxState::SetPShader(ID3D11PixelShader* shader)
|
void EmuGfxState::SetPShader(ID3D11PixelShader* shader)
|
||||||
{
|
{
|
||||||
if (pixelshader) pixelshader->Release();
|
if (pixelshader) pixelshader->Release();
|
||||||
pixelshader = shader;
|
pixelshader = shader;
|
||||||
if (shader) shader->AddRef();
|
if (shader) shader->AddRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuGfxState::SetInputElements(const D3D11_INPUT_ELEMENT_DESC* elems, UINT num)
|
void EmuGfxState::SetInputElements(const D3D11_INPUT_ELEMENT_DESC* elems, UINT num)
|
||||||
{
|
{
|
||||||
num_inp_elems = num;
|
num_inp_elems = num;
|
||||||
memcpy(inp_elems, elems, num*sizeof(D3D11_INPUT_ELEMENT_DESC));
|
memcpy(inp_elems, elems, num*sizeof(D3D11_INPUT_ELEMENT_DESC));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuGfxState::SetShaderResource(unsigned int stage, ID3D11ShaderResourceView* srv)
|
void EmuGfxState::SetShaderResource(unsigned int stage, ID3D11ShaderResourceView* srv)
|
||||||
{
|
{
|
||||||
if (shader_resources[stage])
|
if (shader_resources[stage])
|
||||||
shader_resources[stage]->Release();
|
shader_resources[stage]->Release();
|
||||||
shader_resources[stage] = srv;
|
shader_resources[stage] = srv;
|
||||||
if (srv)
|
if (srv)
|
||||||
srv->AddRef();
|
srv->AddRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuGfxState::ApplyState()
|
void EmuGfxState::ApplyState()
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
// input layout (only needs to be updated if the vertex shader signature changed)
|
// input layout (only needs to be updated if the vertex shader signature changed)
|
||||||
if (vshaderchanged)
|
if (vshaderchanged)
|
||||||
{
|
{
|
||||||
SAFE_RELEASE(inp_layout);
|
SAFE_RELEASE(inp_layout);
|
||||||
hr = D3D::device->CreateInputLayout(inp_elems, num_inp_elems, vsbytecode->Data(), vsbytecode->Size(), &inp_layout);
|
hr = D3D::device->CreateInputLayout(inp_elems, num_inp_elems, vsbytecode->Data(), vsbytecode->Size(), &inp_layout);
|
||||||
if (FAILED(hr)) PanicAlert("Failed to create input layout, %s %d\n", __FILE__, __LINE__);
|
if (FAILED(hr)) PanicAlert("Failed to create input layout, %s %d\n", __FILE__, __LINE__);
|
||||||
SetDebugObjectName((ID3D11DeviceChild*)inp_layout, "an input layout of EmuGfxState");
|
SetDebugObjectName((ID3D11DeviceChild*)inp_layout, "an input layout of EmuGfxState");
|
||||||
vshaderchanged = false;
|
vshaderchanged = false;
|
||||||
}
|
}
|
||||||
D3D::context->IASetInputLayout(inp_layout);
|
D3D::context->IASetInputLayout(inp_layout);
|
||||||
|
|
||||||
// vertex shader
|
// vertex shader
|
||||||
// TODO: divide the global variables of the generated shaders into about 5 constant buffers
|
// TODO: divide the global variables of the generated shaders into about 5 constant buffers
|
||||||
// TODO: improve interaction between EmuGfxState and global state management, so that we don't need to set the constant buffers every time
|
// TODO: improve interaction between EmuGfxState and global state management, so that we don't need to set the constant buffers every time
|
||||||
if (!vscbuf)
|
if (!vscbuf)
|
||||||
{
|
{
|
||||||
unsigned int size = ((sizeof(vsconstants))&(~0xf))+0x10; // must be a multiple of 16
|
unsigned int size = ((sizeof(vsconstants))&(~0xf))+0x10; // must be a multiple of 16
|
||||||
D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(size, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(size, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
||||||
hr = device->CreateBuffer(&cbdesc, NULL, &vscbuf);
|
hr = device->CreateBuffer(&cbdesc, NULL, &vscbuf);
|
||||||
CHECK(hr==S_OK, "Create vertex shader constant buffer (size=%u)", size);
|
CHECK(hr==S_OK, "Create vertex shader constant buffer (size=%u)", size);
|
||||||
SetDebugObjectName((ID3D11DeviceChild*)vscbuf, "a vertex shader constant buffer of EmuGfxState");
|
SetDebugObjectName((ID3D11DeviceChild*)vscbuf, "a vertex shader constant buffer of EmuGfxState");
|
||||||
}
|
}
|
||||||
if (vscbufchanged)
|
if (vscbufchanged)
|
||||||
{
|
{
|
||||||
D3D11_MAPPED_SUBRESOURCE map;
|
D3D11_MAPPED_SUBRESOURCE map;
|
||||||
context->Map(vscbuf, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
context->Map(vscbuf, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
||||||
memcpy(map.pData, vsconstants, sizeof(vsconstants));
|
memcpy(map.pData, vsconstants, sizeof(vsconstants));
|
||||||
context->Unmap(vscbuf, 0);
|
context->Unmap(vscbuf, 0);
|
||||||
}
|
}
|
||||||
D3D::context->VSSetConstantBuffers(0, 1, &vscbuf);
|
D3D::context->VSSetConstantBuffers(0, 1, &vscbuf);
|
||||||
|
|
||||||
// pixel shader
|
// pixel shader
|
||||||
if (!pscbuf)
|
if (!pscbuf)
|
||||||
{
|
{
|
||||||
unsigned int size = ((sizeof(psconstants))&(~0xf))+0x10; // must be a multiple of 16
|
unsigned int size = ((sizeof(psconstants))&(~0xf))+0x10; // must be a multiple of 16
|
||||||
D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(size, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(size, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
||||||
device->CreateBuffer(&cbdesc, NULL, &pscbuf);
|
device->CreateBuffer(&cbdesc, NULL, &pscbuf);
|
||||||
CHECK(hr==S_OK, "Create pixel shader constant buffer (size=%u)", size);
|
CHECK(hr==S_OK, "Create pixel shader constant buffer (size=%u)", size);
|
||||||
SetDebugObjectName((ID3D11DeviceChild*)pscbuf, "a pixel shader constant buffer of EmuGfxState");
|
SetDebugObjectName((ID3D11DeviceChild*)pscbuf, "a pixel shader constant buffer of EmuGfxState");
|
||||||
}
|
}
|
||||||
if (pscbufchanged)
|
if (pscbufchanged)
|
||||||
{
|
{
|
||||||
D3D11_MAPPED_SUBRESOURCE map;
|
D3D11_MAPPED_SUBRESOURCE map;
|
||||||
context->Map(pscbuf, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
context->Map(pscbuf, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
||||||
memcpy(map.pData, psconstants, sizeof(psconstants));
|
memcpy(map.pData, psconstants, sizeof(psconstants));
|
||||||
context->Unmap(pscbuf, 0);
|
context->Unmap(pscbuf, 0);
|
||||||
pscbufchanged = false;
|
pscbufchanged = false;
|
||||||
}
|
}
|
||||||
D3D::context->PSSetConstantBuffers(0, 1, &pscbuf);
|
D3D::context->PSSetConstantBuffers(0, 1, &pscbuf);
|
||||||
|
|
||||||
ID3D11SamplerState* samplerstate[8];
|
ID3D11SamplerState* samplerstate[8];
|
||||||
for (unsigned int stage = 0; stage < 8; stage++)
|
for (unsigned int stage = 0; stage < 8; stage++)
|
||||||
{
|
{
|
||||||
if (shader_resources[stage])
|
if (shader_resources[stage])
|
||||||
{
|
{
|
||||||
if(g_ActiveConfig.iMaxAnisotropy > 1) samplerdesc[stage].Filter = D3D11_FILTER_ANISOTROPIC;
|
if(g_ActiveConfig.iMaxAnisotropy > 1) samplerdesc[stage].Filter = D3D11_FILTER_ANISOTROPIC;
|
||||||
hr = D3D::device->CreateSamplerState(&samplerdesc[stage], &samplerstate[stage]);
|
hr = D3D::device->CreateSamplerState(&samplerdesc[stage], &samplerstate[stage]);
|
||||||
if (FAILED(hr)) PanicAlert("Fail %s %d, stage=%d\n", __FILE__, __LINE__, stage);
|
if (FAILED(hr)) PanicAlert("Fail %s %d, stage=%d\n", __FILE__, __LINE__, stage);
|
||||||
else SetDebugObjectName((ID3D11DeviceChild*)samplerstate[stage], "a sampler state of EmuGfxState");
|
else SetDebugObjectName((ID3D11DeviceChild*)samplerstate[stage], "a sampler state of EmuGfxState");
|
||||||
}
|
}
|
||||||
else samplerstate[stage] = NULL;
|
else samplerstate[stage] = NULL;
|
||||||
}
|
}
|
||||||
D3D::context->PSSetSamplers(0, 8, samplerstate);
|
D3D::context->PSSetSamplers(0, 8, samplerstate);
|
||||||
for (unsigned int stage = 0; stage < 8; stage++)
|
for (unsigned int stage = 0; stage < 8; stage++)
|
||||||
SAFE_RELEASE(samplerstate[stage]);
|
SAFE_RELEASE(samplerstate[stage]);
|
||||||
|
|
||||||
ID3D11BlendState* blstate;
|
ID3D11BlendState* blstate;
|
||||||
hr = device->CreateBlendState(&blenddesc, &blstate);
|
hr = device->CreateBlendState(&blenddesc, &blstate);
|
||||||
if (FAILED(hr)) PanicAlert("Failed to create blend state at %s %d\n", __FILE__, __LINE__);
|
if (FAILED(hr)) PanicAlert("Failed to create blend state at %s %d\n", __FILE__, __LINE__);
|
||||||
stateman->PushBlendState(blstate);
|
stateman->PushBlendState(blstate);
|
||||||
SetDebugObjectName((ID3D11DeviceChild*)blstate, "a blend state of EmuGfxState");
|
SetDebugObjectName((ID3D11DeviceChild*)blstate, "a blend state of EmuGfxState");
|
||||||
SAFE_RELEASE(blstate);
|
SAFE_RELEASE(blstate);
|
||||||
|
|
||||||
rastdesc.FillMode = (g_ActiveConfig.bWireFrame) ? D3D11_FILL_WIREFRAME : D3D11_FILL_SOLID;
|
rastdesc.FillMode = (g_ActiveConfig.bWireFrame) ? D3D11_FILL_WIREFRAME : D3D11_FILL_SOLID;
|
||||||
ID3D11RasterizerState* raststate;
|
ID3D11RasterizerState* raststate;
|
||||||
hr = device->CreateRasterizerState(&rastdesc, &raststate);
|
hr = device->CreateRasterizerState(&rastdesc, &raststate);
|
||||||
if (FAILED(hr)) PanicAlert("Failed to create rasterizer state at %s %d\n", __FILE__, __LINE__);
|
if (FAILED(hr)) PanicAlert("Failed to create rasterizer state at %s %d\n", __FILE__, __LINE__);
|
||||||
SetDebugObjectName((ID3D11DeviceChild*)raststate, "a rasterizer state of EmuGfxState");
|
SetDebugObjectName((ID3D11DeviceChild*)raststate, "a rasterizer state of EmuGfxState");
|
||||||
stateman->PushRasterizerState(raststate);
|
stateman->PushRasterizerState(raststate);
|
||||||
SAFE_RELEASE(raststate);
|
SAFE_RELEASE(raststate);
|
||||||
|
|
||||||
ID3D11DepthStencilState* depth_state;
|
ID3D11DepthStencilState* depth_state;
|
||||||
hr = device->CreateDepthStencilState(&depthdesc, &depth_state);
|
hr = device->CreateDepthStencilState(&depthdesc, &depth_state);
|
||||||
if (SUCCEEDED(hr)) SetDebugObjectName((ID3D11DeviceChild*)depth_state, "a depth-stencil state of EmuGfxState");
|
if (SUCCEEDED(hr)) SetDebugObjectName((ID3D11DeviceChild*)depth_state, "a depth-stencil state of EmuGfxState");
|
||||||
else PanicAlert("Failed to create depth state at %s %d\n", __FILE__, __LINE__);
|
else PanicAlert("Failed to create depth state at %s %d\n", __FILE__, __LINE__);
|
||||||
D3D::stateman->PushDepthState(depth_state);
|
D3D::stateman->PushDepthState(depth_state);
|
||||||
SAFE_RELEASE(depth_state);
|
SAFE_RELEASE(depth_state);
|
||||||
|
|
||||||
context->PSSetShader(pixelshader, NULL, 0);
|
context->PSSetShader(pixelshader, NULL, 0);
|
||||||
context->VSSetShader(vertexshader, NULL, 0);
|
context->VSSetShader(vertexshader, NULL, 0);
|
||||||
context->PSSetShaderResources(0, 8, shader_resources);
|
context->PSSetShaderResources(0, 8, shader_resources);
|
||||||
|
|
||||||
stateman->Apply();
|
stateman->Apply();
|
||||||
apply_called = true;
|
apply_called = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuGfxState::AlphaPass()
|
void EmuGfxState::AlphaPass()
|
||||||
{
|
{
|
||||||
if (!apply_called) ERROR_LOG(VIDEO, "EmuGfxState::AlphaPass called without having called ApplyState before!")
|
if (!apply_called) ERROR_LOG(VIDEO, "EmuGfxState::AlphaPass called without having called ApplyState before!")
|
||||||
else stateman->PopBlendState();
|
else stateman->PopBlendState();
|
||||||
|
|
||||||
// pixel shader for alpha pass is different, so update it
|
// pixel shader for alpha pass is different, so update it
|
||||||
context->PSSetShader(pixelshader, NULL, 0);
|
context->PSSetShader(pixelshader, NULL, 0);
|
||||||
|
|
||||||
ID3D11BlendState* blstate;
|
ID3D11BlendState* blstate;
|
||||||
D3D11_BLEND_DESC desc = blenddesc;
|
D3D11_BLEND_DESC desc = blenddesc;
|
||||||
desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALPHA;
|
desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALPHA;
|
||||||
desc.RenderTarget[0].BlendEnable = FALSE;
|
desc.RenderTarget[0].BlendEnable = FALSE;
|
||||||
HRESULT hr = device->CreateBlendState(&desc, &blstate);
|
HRESULT hr = device->CreateBlendState(&desc, &blstate);
|
||||||
if (FAILED(hr)) PanicAlert("Failed to create blend state at %s %d\n", __FILE__, __LINE__);
|
if (FAILED(hr)) PanicAlert("Failed to create blend state at %s %d\n", __FILE__, __LINE__);
|
||||||
SetDebugObjectName((ID3D11DeviceChild*)blstate, "a blend state of EmuGfxState (created during alpha pass)");
|
SetDebugObjectName((ID3D11DeviceChild*)blstate, "a blend state of EmuGfxState (created during alpha pass)");
|
||||||
stateman->PushBlendState(blstate);
|
stateman->PushBlendState(blstate);
|
||||||
blstate->Release();
|
blstate->Release();
|
||||||
|
|
||||||
stateman->Apply();
|
stateman->Apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuGfxState::Reset()
|
void EmuGfxState::Reset()
|
||||||
{
|
{
|
||||||
for (unsigned int k = 0;k < 8;k++)
|
for (unsigned int k = 0;k < 8;k++)
|
||||||
SAFE_RELEASE(shader_resources[k]);
|
SAFE_RELEASE(shader_resources[k]);
|
||||||
|
|
||||||
context->PSSetShaderResources(0, 8, shader_resources); // unbind all textures
|
context->PSSetShaderResources(0, 8, shader_resources); // unbind all textures
|
||||||
if (apply_called)
|
if (apply_called)
|
||||||
{
|
{
|
||||||
stateman->PopBlendState();
|
stateman->PopBlendState();
|
||||||
stateman->PopDepthState();
|
stateman->PopDepthState();
|
||||||
stateman->PopRasterizerState();
|
stateman->PopRasterizerState();
|
||||||
apply_called = false;
|
apply_called = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuGfxState::SetAlphaBlendEnable(bool enable)
|
void EmuGfxState::SetAlphaBlendEnable(bool enable)
|
||||||
{
|
{
|
||||||
blenddesc.RenderTarget[0].BlendEnable = enable;
|
blenddesc.RenderTarget[0].BlendEnable = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuGfxState::SetRenderTargetWriteMask(UINT8 mask)
|
void EmuGfxState::SetRenderTargetWriteMask(UINT8 mask)
|
||||||
{
|
{
|
||||||
blenddesc.RenderTarget[0].RenderTargetWriteMask = mask;
|
blenddesc.RenderTarget[0].RenderTargetWriteMask = mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuGfxState::SetSrcBlend(D3D11_BLEND val)
|
void EmuGfxState::SetSrcBlend(D3D11_BLEND val)
|
||||||
{
|
{
|
||||||
// TODO: Check whether e.g. the dest color check is needed here
|
// TODO: Check whether e.g. the dest color check is needed here
|
||||||
blenddesc.RenderTarget[0].SrcBlend = val;
|
blenddesc.RenderTarget[0].SrcBlend = val;
|
||||||
if (val == D3D11_BLEND_SRC_COLOR) blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA;
|
if (val == D3D11_BLEND_SRC_COLOR) blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA;
|
||||||
else if (val == D3D11_BLEND_INV_SRC_COLOR) blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
|
else if (val == D3D11_BLEND_INV_SRC_COLOR) blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
|
||||||
else if (val == D3D11_BLEND_DEST_COLOR) blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_DEST_ALPHA;
|
else if (val == D3D11_BLEND_DEST_COLOR) blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_DEST_ALPHA;
|
||||||
else if (val == D3D11_BLEND_INV_DEST_COLOR) blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_DEST_ALPHA;
|
else if (val == D3D11_BLEND_INV_DEST_COLOR) blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_DEST_ALPHA;
|
||||||
else blenddesc.RenderTarget[0].SrcBlendAlpha = val;
|
else blenddesc.RenderTarget[0].SrcBlendAlpha = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuGfxState::SetDestBlend(D3D11_BLEND val)
|
void EmuGfxState::SetDestBlend(D3D11_BLEND val)
|
||||||
{
|
{
|
||||||
// TODO: Check whether e.g. the source color check is needed here
|
// TODO: Check whether e.g. the source color check is needed here
|
||||||
blenddesc.RenderTarget[0].DestBlend = val;
|
blenddesc.RenderTarget[0].DestBlend = val;
|
||||||
if (val == D3D11_BLEND_SRC_COLOR) blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_SRC_ALPHA;
|
if (val == D3D11_BLEND_SRC_COLOR) blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_SRC_ALPHA;
|
||||||
else if (val == D3D11_BLEND_INV_SRC_COLOR) blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
|
else if (val == D3D11_BLEND_INV_SRC_COLOR) blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
|
||||||
else if (val == D3D11_BLEND_DEST_COLOR) blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_DEST_ALPHA;
|
else if (val == D3D11_BLEND_DEST_COLOR) blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_DEST_ALPHA;
|
||||||
else if (val == D3D11_BLEND_INV_DEST_COLOR) blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_DEST_ALPHA;
|
else if (val == D3D11_BLEND_INV_DEST_COLOR) blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_DEST_ALPHA;
|
||||||
else blenddesc.RenderTarget[0].DestBlendAlpha = val;
|
else blenddesc.RenderTarget[0].DestBlendAlpha = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuGfxState::SetBlendOp(D3D11_BLEND_OP val)
|
void EmuGfxState::SetBlendOp(D3D11_BLEND_OP val)
|
||||||
{
|
{
|
||||||
blenddesc.RenderTarget[0].BlendOp = val;
|
blenddesc.RenderTarget[0].BlendOp = val;
|
||||||
blenddesc.RenderTarget[0].BlendOpAlpha = val;
|
blenddesc.RenderTarget[0].BlendOpAlpha = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuGfxState::SetSamplerFilter(DWORD stage, D3D11_FILTER filter)
|
void EmuGfxState::SetSamplerFilter(DWORD stage, D3D11_FILTER filter)
|
||||||
{
|
{
|
||||||
samplerdesc[stage].Filter = filter;
|
samplerdesc[stage].Filter = filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> AutoState<T>::AutoState(const T* object) : state(object)
|
template<typename T> AutoState<T>::AutoState(const T* object) : state(object)
|
||||||
{
|
{
|
||||||
((IUnknown*)state)->AddRef();
|
((IUnknown*)state)->AddRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> AutoState<T>::AutoState(const AutoState<T> &source)
|
template<typename T> AutoState<T>::AutoState(const AutoState<T> &source)
|
||||||
{
|
{
|
||||||
state = source.GetPtr();
|
state = source.GetPtr();
|
||||||
((T*)state)->AddRef();
|
((T*)state)->AddRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> AutoState<T>::~AutoState()
|
template<typename T> AutoState<T>::~AutoState()
|
||||||
{
|
{
|
||||||
if(state) ((T*)state)->Release();
|
if(state) ((T*)state)->Release();
|
||||||
state = NULL;
|
state = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
StateManager::StateManager() : cur_blendstate(NULL), cur_depthstate(NULL), cur_raststate(NULL) {}
|
StateManager::StateManager() : cur_blendstate(NULL), cur_depthstate(NULL), cur_raststate(NULL) {}
|
||||||
|
|
||||||
void StateManager::PushBlendState(const ID3D11BlendState* state) { blendstates.push(AutoBlendState(state)); }
|
void StateManager::PushBlendState(const ID3D11BlendState* state) { blendstates.push(AutoBlendState(state)); }
|
||||||
void StateManager::PushDepthState(const ID3D11DepthStencilState* state) { depthstates.push(AutoDepthStencilState(state)); }
|
void StateManager::PushDepthState(const ID3D11DepthStencilState* state) { depthstates.push(AutoDepthStencilState(state)); }
|
||||||
void StateManager::PushRasterizerState(const ID3D11RasterizerState* state) { raststates.push(AutoRasterizerState(state)); }
|
void StateManager::PushRasterizerState(const ID3D11RasterizerState* state) { raststates.push(AutoRasterizerState(state)); }
|
||||||
void StateManager::PopBlendState() { blendstates.pop(); }
|
void StateManager::PopBlendState() { blendstates.pop(); }
|
||||||
void StateManager::PopDepthState() { depthstates.pop(); }
|
void StateManager::PopDepthState() { depthstates.pop(); }
|
||||||
void StateManager::PopRasterizerState() { raststates.pop(); }
|
void StateManager::PopRasterizerState() { raststates.pop(); }
|
||||||
|
|
||||||
void StateManager::Apply()
|
void StateManager::Apply()
|
||||||
{
|
{
|
||||||
if (!blendstates.empty())
|
if (!blendstates.empty())
|
||||||
{
|
{
|
||||||
if (cur_blendstate != blendstates.top().GetPtr())
|
if (cur_blendstate != blendstates.top().GetPtr())
|
||||||
{
|
{
|
||||||
cur_blendstate = (ID3D11BlendState*)blendstates.top().GetPtr();
|
cur_blendstate = (ID3D11BlendState*)blendstates.top().GetPtr();
|
||||||
D3D::context->OMSetBlendState(cur_blendstate, NULL, 0xFFFFFFFF);
|
D3D::context->OMSetBlendState(cur_blendstate, NULL, 0xFFFFFFFF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else ERROR_LOG(VIDEO, "Tried to apply without blend state!");
|
else ERROR_LOG(VIDEO, "Tried to apply without blend state!");
|
||||||
|
|
||||||
if (!depthstates.empty())
|
if (!depthstates.empty())
|
||||||
{
|
{
|
||||||
if (cur_depthstate != depthstates.top().GetPtr())
|
if (cur_depthstate != depthstates.top().GetPtr())
|
||||||
{
|
{
|
||||||
cur_depthstate = (ID3D11DepthStencilState*)depthstates.top().GetPtr();
|
cur_depthstate = (ID3D11DepthStencilState*)depthstates.top().GetPtr();
|
||||||
D3D::context->OMSetDepthStencilState(cur_depthstate, 0);
|
D3D::context->OMSetDepthStencilState(cur_depthstate, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else ERROR_LOG(VIDEO, "Tried to apply without depth state!");
|
else ERROR_LOG(VIDEO, "Tried to apply without depth state!");
|
||||||
|
|
||||||
if (!raststates.empty())
|
if (!raststates.empty())
|
||||||
{
|
{
|
||||||
if (cur_raststate != raststates.top().GetPtr())
|
if (cur_raststate != raststates.top().GetPtr())
|
||||||
{
|
{
|
||||||
cur_raststate = (ID3D11RasterizerState*)raststates.top().GetPtr();
|
cur_raststate = (ID3D11RasterizerState*)raststates.top().GetPtr();
|
||||||
D3D::context->RSSetState(cur_raststate);
|
D3D::context->RSSetState(cur_raststate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else ERROR_LOG(VIDEO, "Tried to apply without rasterizer state!");
|
else ERROR_LOG(VIDEO, "Tried to apply without rasterizer state!");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,142 +1,142 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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
|
#pragma once
|
||||||
|
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
|
||||||
// VideoCommon
|
// VideoCommon
|
||||||
#include "VertexShaderGen.h"
|
#include "VertexShaderGen.h"
|
||||||
#include "PixelShaderGen.h"
|
#include "PixelShaderGen.h"
|
||||||
|
|
||||||
// DX11
|
// DX11
|
||||||
#include "DX11_D3DBase.h"
|
#include "DX11_D3DBase.h"
|
||||||
#include "DX11_D3DBlob.h"
|
#include "DX11_D3DBlob.h"
|
||||||
|
|
||||||
namespace DX11
|
namespace DX11
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace D3D
|
namespace D3D
|
||||||
{
|
{
|
||||||
|
|
||||||
// stores the pipeline state to use when calling VertexManager::Flush()
|
// stores the pipeline state to use when calling VertexManager::Flush()
|
||||||
class EmuGfxState
|
class EmuGfxState
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
EmuGfxState();
|
EmuGfxState();
|
||||||
~EmuGfxState();
|
~EmuGfxState();
|
||||||
|
|
||||||
void SetVShader(ID3D11VertexShader* shader, D3DBlob* bcode);
|
void SetVShader(ID3D11VertexShader* shader, D3DBlob* bcode);
|
||||||
void SetPShader(ID3D11PixelShader* shader);
|
void SetPShader(ID3D11PixelShader* shader);
|
||||||
void SetInputElements(const D3D11_INPUT_ELEMENT_DESC* elems, UINT num);
|
void SetInputElements(const D3D11_INPUT_ELEMENT_DESC* elems, UINT num);
|
||||||
void SetShaderResource(unsigned int stage, ID3D11ShaderResourceView* srv);
|
void SetShaderResource(unsigned int stage, ID3D11ShaderResourceView* srv);
|
||||||
|
|
||||||
void ApplyState(); // apply current state
|
void ApplyState(); // apply current state
|
||||||
void AlphaPass(); // only modify the current state to enable the alpha pass
|
void AlphaPass(); // only modify the current state to enable the alpha pass
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
// blend state
|
// blend state
|
||||||
void SetAlphaBlendEnable(bool enable);
|
void SetAlphaBlendEnable(bool enable);
|
||||||
void SetRenderTargetWriteMask(UINT8 mask);
|
void SetRenderTargetWriteMask(UINT8 mask);
|
||||||
void SetSrcBlend(D3D11_BLEND val);
|
void SetSrcBlend(D3D11_BLEND val);
|
||||||
void SetDestBlend(D3D11_BLEND val);
|
void SetDestBlend(D3D11_BLEND val);
|
||||||
void SetBlendOp(D3D11_BLEND_OP val);
|
void SetBlendOp(D3D11_BLEND_OP val);
|
||||||
|
|
||||||
// sampler states
|
// sampler states
|
||||||
void SetSamplerFilter(DWORD stage, D3D11_FILTER filter);
|
void SetSamplerFilter(DWORD stage, D3D11_FILTER filter);
|
||||||
|
|
||||||
// TODO: add methods for changing the other states instead of modifying them directly
|
// TODO: add methods for changing the other states instead of modifying them directly
|
||||||
|
|
||||||
D3D11_SAMPLER_DESC samplerdesc[8];
|
D3D11_SAMPLER_DESC samplerdesc[8];
|
||||||
D3D11_RASTERIZER_DESC rastdesc;
|
D3D11_RASTERIZER_DESC rastdesc;
|
||||||
D3D11_DEPTH_STENCIL_DESC depthdesc;
|
D3D11_DEPTH_STENCIL_DESC depthdesc;
|
||||||
|
|
||||||
float psconstants[C_PENVCONST_END*4];
|
float psconstants[C_PENVCONST_END*4];
|
||||||
float vsconstants[C_VENVCONST_END*4];
|
float vsconstants[C_VENVCONST_END*4];
|
||||||
bool vscbufchanged;
|
bool vscbufchanged;
|
||||||
bool pscbufchanged;
|
bool pscbufchanged;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ID3D11VertexShader* vertexshader;
|
ID3D11VertexShader* vertexshader;
|
||||||
D3DBlob* vsbytecode;
|
D3DBlob* vsbytecode;
|
||||||
ID3D11PixelShader* pixelshader;
|
ID3D11PixelShader* pixelshader;
|
||||||
D3DBlob* psbytecode;
|
D3DBlob* psbytecode;
|
||||||
bool vshaderchanged;
|
bool vshaderchanged;
|
||||||
|
|
||||||
ID3D11Buffer* vscbuf;
|
ID3D11Buffer* vscbuf;
|
||||||
ID3D11Buffer* pscbuf;
|
ID3D11Buffer* pscbuf;
|
||||||
|
|
||||||
ID3D11InputLayout* inp_layout;
|
ID3D11InputLayout* inp_layout;
|
||||||
D3D11_INPUT_ELEMENT_DESC inp_elems[32];
|
D3D11_INPUT_ELEMENT_DESC inp_elems[32];
|
||||||
int num_inp_elems;
|
int num_inp_elems;
|
||||||
|
|
||||||
ID3D11ShaderResourceView* shader_resources[8];
|
ID3D11ShaderResourceView* shader_resources[8];
|
||||||
D3D11_BLEND_DESC blenddesc;
|
D3D11_BLEND_DESC blenddesc;
|
||||||
|
|
||||||
bool apply_called;
|
bool apply_called;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T> class AutoState
|
template<typename T> class AutoState
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AutoState(const T* object);
|
AutoState(const T* object);
|
||||||
AutoState(const AutoState<T> &source);
|
AutoState(const AutoState<T> &source);
|
||||||
~AutoState();
|
~AutoState();
|
||||||
|
|
||||||
const inline T* GetPtr() const { return state; }
|
const inline T* GetPtr() const { return state; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const T* state;
|
const T* state;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef AutoState<ID3D11BlendState> AutoBlendState;
|
typedef AutoState<ID3D11BlendState> AutoBlendState;
|
||||||
typedef AutoState<ID3D11DepthStencilState> AutoDepthStencilState;
|
typedef AutoState<ID3D11DepthStencilState> AutoDepthStencilState;
|
||||||
typedef AutoState<ID3D11RasterizerState> AutoRasterizerState;
|
typedef AutoState<ID3D11RasterizerState> AutoRasterizerState;
|
||||||
|
|
||||||
class StateManager
|
class StateManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
StateManager();
|
StateManager();
|
||||||
|
|
||||||
// call any of these to change the affected states
|
// call any of these to change the affected states
|
||||||
void PushBlendState(const ID3D11BlendState* state);
|
void PushBlendState(const ID3D11BlendState* state);
|
||||||
void PushDepthState(const ID3D11DepthStencilState* state);
|
void PushDepthState(const ID3D11DepthStencilState* state);
|
||||||
void PushRasterizerState(const ID3D11RasterizerState* state);
|
void PushRasterizerState(const ID3D11RasterizerState* state);
|
||||||
|
|
||||||
// call these after drawing
|
// call these after drawing
|
||||||
void PopBlendState();
|
void PopBlendState();
|
||||||
void PopDepthState();
|
void PopDepthState();
|
||||||
void PopRasterizerState();
|
void PopRasterizerState();
|
||||||
|
|
||||||
// call this before any drawing operation if states could have changed meanwhile
|
// call this before any drawing operation if states could have changed meanwhile
|
||||||
void Apply();
|
void Apply();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::stack<AutoBlendState> blendstates;
|
std::stack<AutoBlendState> blendstates;
|
||||||
std::stack<AutoDepthStencilState> depthstates;
|
std::stack<AutoDepthStencilState> depthstates;
|
||||||
std::stack<AutoRasterizerState> raststates;
|
std::stack<AutoRasterizerState> raststates;
|
||||||
ID3D11BlendState* cur_blendstate;
|
ID3D11BlendState* cur_blendstate;
|
||||||
ID3D11DepthStencilState* cur_depthstate;
|
ID3D11DepthStencilState* cur_depthstate;
|
||||||
ID3D11RasterizerState* cur_raststate;
|
ID3D11RasterizerState* cur_raststate;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern EmuGfxState* gfxstate;
|
extern EmuGfxState* gfxstate;
|
||||||
extern StateManager* stateman;
|
extern StateManager* stateman;
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,150 +1,150 @@
|
|||||||
|
|
||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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/
|
||||||
|
|
||||||
// Common
|
// Common
|
||||||
#include "MemoryUtil.h"
|
#include "MemoryUtil.h"
|
||||||
#include "x64Emitter.h"
|
#include "x64Emitter.h"
|
||||||
#include "ABI.h"
|
#include "ABI.h"
|
||||||
|
|
||||||
// VideoCommon
|
// VideoCommon
|
||||||
#include "Profiler.h"
|
#include "Profiler.h"
|
||||||
#include "CPMemory.h"
|
#include "CPMemory.h"
|
||||||
#include "VertexShaderGen.h"
|
#include "VertexShaderGen.h"
|
||||||
#include "NativeVertexFormat.h"
|
#include "NativeVertexFormat.h"
|
||||||
|
|
||||||
// DX11
|
// DX11
|
||||||
#include "DX11_D3DBase.h"
|
#include "DX11_D3DBase.h"
|
||||||
#include "DX11_VertexShaderCache.h"
|
#include "DX11_VertexShaderCache.h"
|
||||||
#include "DX11_VertexManager.h"
|
#include "DX11_VertexManager.h"
|
||||||
|
|
||||||
namespace DX11
|
namespace DX11
|
||||||
{
|
{
|
||||||
|
|
||||||
class D3DVertexFormat : public NativeVertexFormat
|
class D3DVertexFormat : public NativeVertexFormat
|
||||||
{
|
{
|
||||||
D3D11_INPUT_ELEMENT_DESC m_elems[32];
|
D3D11_INPUT_ELEMENT_DESC m_elems[32];
|
||||||
UINT m_num_elems;
|
UINT m_num_elems;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
D3DVertexFormat() : m_num_elems(0) {}
|
D3DVertexFormat() : m_num_elems(0) {}
|
||||||
void Initialize(const PortableVertexDeclaration &_vtx_decl);
|
void Initialize(const PortableVertexDeclaration &_vtx_decl);
|
||||||
void SetupVertexPointers() const;
|
void SetupVertexPointers() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
NativeVertexFormat* VertexManager::CreateNativeVertexFormat()
|
NativeVertexFormat* VertexManager::CreateNativeVertexFormat()
|
||||||
{
|
{
|
||||||
return new D3DVertexFormat;
|
return new D3DVertexFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
DXGI_FORMAT VarToD3D(VarType t, int size)
|
DXGI_FORMAT VarToD3D(VarType t, int size)
|
||||||
{
|
{
|
||||||
DXGI_FORMAT retval = DXGI_FORMAT_UNKNOWN;
|
DXGI_FORMAT retval = DXGI_FORMAT_UNKNOWN;
|
||||||
static const DXGI_FORMAT lookup1[5] = {
|
static const DXGI_FORMAT lookup1[5] = {
|
||||||
DXGI_FORMAT_R8_SNORM, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R16_SNORM, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R32_FLOAT
|
DXGI_FORMAT_R8_SNORM, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R16_SNORM, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R32_FLOAT
|
||||||
};
|
};
|
||||||
static const DXGI_FORMAT lookup2[5] = {
|
static const DXGI_FORMAT lookup2[5] = {
|
||||||
DXGI_FORMAT_R8G8_SNORM, DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R16G16_SNORM, DXGI_FORMAT_R16G16_UNORM, DXGI_FORMAT_R32G32_FLOAT
|
DXGI_FORMAT_R8G8_SNORM, DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R16G16_SNORM, DXGI_FORMAT_R16G16_UNORM, DXGI_FORMAT_R32G32_FLOAT
|
||||||
};
|
};
|
||||||
static const DXGI_FORMAT lookup3[5] = {
|
static const DXGI_FORMAT lookup3[5] = {
|
||||||
DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_R32G32B32_FLOAT
|
DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_R32G32B32_FLOAT
|
||||||
};
|
};
|
||||||
static const DXGI_FORMAT lookup4[5] = {
|
static const DXGI_FORMAT lookup4[5] = {
|
||||||
DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R16G16B16A16_SNORM, DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_R32G32B32A32_FLOAT
|
DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R16G16B16A16_SNORM, DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_R32G32B32A32_FLOAT
|
||||||
};
|
};
|
||||||
|
|
||||||
switch (size)
|
switch (size)
|
||||||
{
|
{
|
||||||
case 1: retval = lookup1[t]; break;
|
case 1: retval = lookup1[t]; break;
|
||||||
case 2: retval = lookup2[t]; break;
|
case 2: retval = lookup2[t]; break;
|
||||||
case 3: retval = lookup3[t]; break;
|
case 3: retval = lookup3[t]; break;
|
||||||
case 4: retval = lookup4[t]; break;
|
case 4: retval = lookup4[t]; break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
if (retval == DXGI_FORMAT_UNKNOWN)
|
if (retval == DXGI_FORMAT_UNKNOWN)
|
||||||
{
|
{
|
||||||
PanicAlert("VarToD3D: Invalid type/size combo %i , %i", (int)t, size);
|
PanicAlert("VarToD3D: Invalid type/size combo %i , %i", (int)t, size);
|
||||||
}
|
}
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3DVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl)
|
void D3DVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl)
|
||||||
{
|
{
|
||||||
vertex_stride = _vtx_decl.stride;
|
vertex_stride = _vtx_decl.stride;
|
||||||
memset(m_elems, 0, sizeof(m_elems));
|
memset(m_elems, 0, sizeof(m_elems));
|
||||||
|
|
||||||
m_elems[m_num_elems].SemanticName = "POSITION";
|
m_elems[m_num_elems].SemanticName = "POSITION";
|
||||||
m_elems[m_num_elems].AlignedByteOffset = 0;
|
m_elems[m_num_elems].AlignedByteOffset = 0;
|
||||||
m_elems[m_num_elems].Format = DXGI_FORMAT_R32G32B32_FLOAT;
|
m_elems[m_num_elems].Format = DXGI_FORMAT_R32G32B32_FLOAT;
|
||||||
m_elems[m_num_elems].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
|
m_elems[m_num_elems].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
|
||||||
++m_num_elems;
|
++m_num_elems;
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
if (_vtx_decl.normal_offset[i] > 0)
|
if (_vtx_decl.normal_offset[i] > 0)
|
||||||
{
|
{
|
||||||
m_elems[m_num_elems].SemanticName = "NORMAL";
|
m_elems[m_num_elems].SemanticName = "NORMAL";
|
||||||
m_elems[m_num_elems].SemanticIndex = i;
|
m_elems[m_num_elems].SemanticIndex = i;
|
||||||
m_elems[m_num_elems].AlignedByteOffset = _vtx_decl.normal_offset[i];
|
m_elems[m_num_elems].AlignedByteOffset = _vtx_decl.normal_offset[i];
|
||||||
m_elems[m_num_elems].Format = VarToD3D(_vtx_decl.normal_gl_type, _vtx_decl.normal_gl_size);
|
m_elems[m_num_elems].Format = VarToD3D(_vtx_decl.normal_gl_type, _vtx_decl.normal_gl_size);
|
||||||
m_elems[m_num_elems].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
|
m_elems[m_num_elems].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
|
||||||
++m_num_elems;
|
++m_num_elems;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++)
|
for (int i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
if (_vtx_decl.color_offset[i] > 0)
|
if (_vtx_decl.color_offset[i] > 0)
|
||||||
{
|
{
|
||||||
m_elems[m_num_elems].SemanticName = "COLOR";
|
m_elems[m_num_elems].SemanticName = "COLOR";
|
||||||
m_elems[m_num_elems].SemanticIndex = i;
|
m_elems[m_num_elems].SemanticIndex = i;
|
||||||
m_elems[m_num_elems].AlignedByteOffset = _vtx_decl.color_offset[i];
|
m_elems[m_num_elems].AlignedByteOffset = _vtx_decl.color_offset[i];
|
||||||
m_elems[m_num_elems].Format = VarToD3D(_vtx_decl.color_gl_type, 4);
|
m_elems[m_num_elems].Format = VarToD3D(_vtx_decl.color_gl_type, 4);
|
||||||
m_elems[m_num_elems].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
|
m_elems[m_num_elems].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
|
||||||
++m_num_elems;
|
++m_num_elems;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
if (_vtx_decl.texcoord_offset[i] > 0)
|
if (_vtx_decl.texcoord_offset[i] > 0)
|
||||||
{
|
{
|
||||||
m_elems[m_num_elems].SemanticName = "TEXCOORD";
|
m_elems[m_num_elems].SemanticName = "TEXCOORD";
|
||||||
m_elems[m_num_elems].SemanticIndex = i;
|
m_elems[m_num_elems].SemanticIndex = i;
|
||||||
m_elems[m_num_elems].AlignedByteOffset = _vtx_decl.texcoord_offset[i];
|
m_elems[m_num_elems].AlignedByteOffset = _vtx_decl.texcoord_offset[i];
|
||||||
m_elems[m_num_elems].Format = VarToD3D(_vtx_decl.texcoord_gl_type[i], _vtx_decl.texcoord_size[i]);
|
m_elems[m_num_elems].Format = VarToD3D(_vtx_decl.texcoord_gl_type[i], _vtx_decl.texcoord_size[i]);
|
||||||
m_elems[m_num_elems].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
|
m_elems[m_num_elems].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
|
||||||
++m_num_elems;
|
++m_num_elems;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_vtx_decl.posmtx_offset != -1)
|
if (_vtx_decl.posmtx_offset != -1)
|
||||||
{
|
{
|
||||||
m_elems[m_num_elems].SemanticName = "BLENDINDICES";
|
m_elems[m_num_elems].SemanticName = "BLENDINDICES";
|
||||||
m_elems[m_num_elems].AlignedByteOffset = _vtx_decl.posmtx_offset;
|
m_elems[m_num_elems].AlignedByteOffset = _vtx_decl.posmtx_offset;
|
||||||
m_elems[m_num_elems].Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
m_elems[m_num_elems].Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
m_elems[m_num_elems].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
|
m_elems[m_num_elems].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
|
||||||
++m_num_elems;
|
++m_num_elems;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3DVertexFormat::SetupVertexPointers() const
|
void D3DVertexFormat::SetupVertexPointers() const
|
||||||
{
|
{
|
||||||
D3D::gfxstate->SetInputElements(m_elems, m_num_elems);
|
D3D::gfxstate->SetInputElements(m_elems, m_num_elems);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,306 +1,306 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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/
|
||||||
|
|
||||||
// Common
|
// Common
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "FileUtil.h"
|
#include "FileUtil.h"
|
||||||
#include "LinearDiskCache.h"
|
#include "LinearDiskCache.h"
|
||||||
|
|
||||||
// VideoCommon
|
// VideoCommon
|
||||||
#include "Statistics.h"
|
#include "Statistics.h"
|
||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
#include "VertexLoader.h"
|
#include "VertexLoader.h"
|
||||||
#include "BPMemory.h"
|
#include "BPMemory.h"
|
||||||
#include "XFMemory.h"
|
#include "XFMemory.h"
|
||||||
#include "ImageWrite.h"
|
#include "ImageWrite.h"
|
||||||
#include "PixelShaderGen.h"
|
#include "PixelShaderGen.h"
|
||||||
#include "PixelShaderManager.h"
|
#include "PixelShaderManager.h"
|
||||||
|
|
||||||
// DX11
|
// DX11
|
||||||
#include "DX11_D3DBase.h"
|
#include "DX11_D3DBase.h"
|
||||||
#include "DX11_D3DShader.h"
|
#include "DX11_D3DShader.h"
|
||||||
#include "DX11_PixelShaderCache.h"
|
#include "DX11_PixelShaderCache.h"
|
||||||
|
|
||||||
#include <D3Dcompiler.h>
|
#include <D3Dcompiler.h>
|
||||||
|
|
||||||
#include "../Main.h"
|
#include "../Main.h"
|
||||||
|
|
||||||
namespace DX11
|
namespace DX11
|
||||||
{
|
{
|
||||||
|
|
||||||
PixelShaderCache::PSCache PixelShaderCache::PixelShaders;
|
PixelShaderCache::PSCache PixelShaderCache::PixelShaders;
|
||||||
const PixelShaderCache::PSCacheEntry* PixelShaderCache::last_entry;
|
const PixelShaderCache::PSCacheEntry* PixelShaderCache::last_entry;
|
||||||
|
|
||||||
LinearDiskCache g_ps_disk_cache;
|
LinearDiskCache g_ps_disk_cache;
|
||||||
|
|
||||||
ID3D11PixelShader* s_ColorMatrixProgram = NULL;
|
ID3D11PixelShader* s_ColorMatrixProgram = NULL;
|
||||||
ID3D11PixelShader* s_ColorCopyProgram = NULL;
|
ID3D11PixelShader* s_ColorCopyProgram = NULL;
|
||||||
ID3D11PixelShader* s_DepthMatrixProgram = NULL;
|
ID3D11PixelShader* s_DepthMatrixProgram = NULL;
|
||||||
ID3D11PixelShader* s_ClearProgram = NULL;
|
ID3D11PixelShader* s_ClearProgram = NULL;
|
||||||
|
|
||||||
const char clear_program_code[] = {
|
const char clear_program_code[] = {
|
||||||
"void main(\n"
|
"void main(\n"
|
||||||
"out float4 ocol0 : SV_Target,\n"
|
"out float4 ocol0 : SV_Target,\n"
|
||||||
"in float4 pos : SV_Position,\n"
|
"in float4 pos : SV_Position,\n"
|
||||||
"in float4 incol0 : COLOR0){\n"
|
"in float4 incol0 : COLOR0){\n"
|
||||||
"ocol0 = incol0;\n"
|
"ocol0 = incol0;\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
};
|
};
|
||||||
|
|
||||||
const char color_copy_program_code[] = {
|
const char color_copy_program_code[] = {
|
||||||
"sampler samp0 : register(s0);\n"
|
"sampler samp0 : register(s0);\n"
|
||||||
"Texture2D Tex0 : register(t0);\n"
|
"Texture2D Tex0 : register(t0);\n"
|
||||||
"void main(\n"
|
"void main(\n"
|
||||||
"out float4 ocol0 : SV_Target,\n"
|
"out float4 ocol0 : SV_Target,\n"
|
||||||
"in float4 pos : SV_Position,\n"
|
"in float4 pos : SV_Position,\n"
|
||||||
"in float2 uv0 : TEXCOORD0){\n"
|
"in float2 uv0 : TEXCOORD0){\n"
|
||||||
"ocol0 = Tex0.Sample(samp0,uv0);\n"
|
"ocol0 = Tex0.Sample(samp0,uv0);\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
};
|
};
|
||||||
|
|
||||||
const char color_matrix_program_code[] = {
|
const char color_matrix_program_code[] = {
|
||||||
"sampler samp0 : register(s0);\n"
|
"sampler samp0 : register(s0);\n"
|
||||||
"Texture2D Tex0 : register(t0);\n"
|
"Texture2D Tex0 : register(t0);\n"
|
||||||
"uniform float4 cColMatrix[5] : register(c0);\n"
|
"uniform float4 cColMatrix[5] : register(c0);\n"
|
||||||
"void main(\n"
|
"void main(\n"
|
||||||
"out float4 ocol0 : SV_Target,\n"
|
"out float4 ocol0 : SV_Target,\n"
|
||||||
"in float4 pos : SV_Position,\n"
|
"in float4 pos : SV_Position,\n"
|
||||||
" in float2 uv0 : TEXCOORD0){\n"
|
" in float2 uv0 : TEXCOORD0){\n"
|
||||||
"float4 texcol = Tex0.Sample(samp0,uv0);\n"
|
"float4 texcol = Tex0.Sample(samp0,uv0);\n"
|
||||||
"ocol0 = float4(dot(texcol,cColMatrix[0]),dot(texcol,cColMatrix[1]),dot(texcol,cColMatrix[2]),dot(texcol,cColMatrix[3])) + cColMatrix[4];\n"
|
"ocol0 = float4(dot(texcol,cColMatrix[0]),dot(texcol,cColMatrix[1]),dot(texcol,cColMatrix[2]),dot(texcol,cColMatrix[3])) + cColMatrix[4];\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
};
|
};
|
||||||
|
|
||||||
const char depth_matrix_program[] = {
|
const char depth_matrix_program[] = {
|
||||||
"sampler samp0 : register(s0);\n"
|
"sampler samp0 : register(s0);\n"
|
||||||
"Texture2D Tex0 : register(t0);\n"
|
"Texture2D Tex0 : register(t0);\n"
|
||||||
"uniform float4 cColMatrix[5] : register(c0);\n"
|
"uniform float4 cColMatrix[5] : register(c0);\n"
|
||||||
"void main(\n"
|
"void main(\n"
|
||||||
"out float4 ocol0 : SV_Target,\n"
|
"out float4 ocol0 : SV_Target,\n"
|
||||||
" in float4 pos : SV_Position,\n"
|
" in float4 pos : SV_Position,\n"
|
||||||
" in float2 uv0 : TEXCOORD0){\n"
|
" in float2 uv0 : TEXCOORD0){\n"
|
||||||
"float4 texcol = Tex0.Sample(samp0,uv0);\n"
|
"float4 texcol = Tex0.Sample(samp0,uv0);\n"
|
||||||
"float4 EncodedDepth = frac((texcol.r * (16777215.0f/16777216.0f)) * float4(1.0f,255.0f,255.0f*255.0f,255.0f*255.0f*255.0f));\n"
|
"float4 EncodedDepth = frac((texcol.r * (16777215.0f/16777216.0f)) * float4(1.0f,255.0f,255.0f*255.0f,255.0f*255.0f*255.0f));\n"
|
||||||
"texcol = float4((EncodedDepth.rgb * (16777216.0f/16777215.0f)),1.0f);\n"
|
"texcol = float4((EncodedDepth.rgb * (16777216.0f/16777215.0f)),1.0f);\n"
|
||||||
"ocol0 = float4(dot(texcol,cColMatrix[0]),dot(texcol,cColMatrix[1]),dot(texcol,cColMatrix[2]),dot(texcol,cColMatrix[3])) + cColMatrix[4];\n"
|
"ocol0 = float4(dot(texcol,cColMatrix[0]),dot(texcol,cColMatrix[1]),dot(texcol,cColMatrix[2]),dot(texcol,cColMatrix[3])) + cColMatrix[4];\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
};
|
};
|
||||||
|
|
||||||
ID3D11PixelShader* PixelShaderCache::GetColorMatrixProgram()
|
ID3D11PixelShader* PixelShaderCache::GetColorMatrixProgram()
|
||||||
{
|
{
|
||||||
return s_ColorMatrixProgram;
|
return s_ColorMatrixProgram;
|
||||||
}
|
}
|
||||||
|
|
||||||
ID3D11PixelShader* PixelShaderCache::GetDepthMatrixProgram()
|
ID3D11PixelShader* PixelShaderCache::GetDepthMatrixProgram()
|
||||||
{
|
{
|
||||||
return s_DepthMatrixProgram;
|
return s_DepthMatrixProgram;
|
||||||
}
|
}
|
||||||
|
|
||||||
ID3D11PixelShader* PixelShaderCache::GetColorCopyProgram()
|
ID3D11PixelShader* PixelShaderCache::GetColorCopyProgram()
|
||||||
{
|
{
|
||||||
return s_ColorCopyProgram;
|
return s_ColorCopyProgram;
|
||||||
}
|
}
|
||||||
|
|
||||||
ID3D11PixelShader* PixelShaderCache::GetClearProgram()
|
ID3D11PixelShader* PixelShaderCache::GetClearProgram()
|
||||||
{
|
{
|
||||||
return s_ClearProgram;
|
return s_ClearProgram;
|
||||||
}
|
}
|
||||||
|
|
||||||
// HACK to avoid some invasive VideoCommon changes
|
// HACK to avoid some invasive VideoCommon changes
|
||||||
// these values are hardcoded, they depend on internal D3DCompile behavior; TODO: Solve this with D3DReflect or something
|
// these values are hardcoded, they depend on internal D3DCompile behavior; TODO: Solve this with D3DReflect or something
|
||||||
// offset given in floats, table index is float4
|
// offset given in floats, table index is float4
|
||||||
unsigned int ps_constant_offset_table[] = {
|
unsigned int ps_constant_offset_table[] = {
|
||||||
0, 4, 8, 12, // C_COLORS, 16
|
0, 4, 8, 12, // C_COLORS, 16
|
||||||
16, 20, 24, 28, // C_KCOLORS, 16
|
16, 20, 24, 28, // C_KCOLORS, 16
|
||||||
32, // C_ALPHA, 4
|
32, // C_ALPHA, 4
|
||||||
36, 40, 44, 48, 52, 56, 60, 64, // C_TEXDIMS, 32
|
36, 40, 44, 48, 52, 56, 60, 64, // C_TEXDIMS, 32
|
||||||
68, 72, // C_ZBIAS, 8
|
68, 72, // C_ZBIAS, 8
|
||||||
76, 80, // C_INDTEXSCALE, 8
|
76, 80, // C_INDTEXSCALE, 8
|
||||||
84, 88, 92, 96, 100, 104, // C_INDTEXMTX, 24
|
84, 88, 92, 96, 100, 104, // C_INDTEXMTX, 24
|
||||||
108, 112, // C_FOG, 8
|
108, 112, // C_FOG, 8
|
||||||
116, 120, 124 ,128, // C_COLORMATRIX, 16
|
116, 120, 124 ,128, // C_COLORMATRIX, 16
|
||||||
132, 136, 140, 144, 148, // C_PLIGHTS0, 20
|
132, 136, 140, 144, 148, // C_PLIGHTS0, 20
|
||||||
152, 156, 160, 164, 168, // C_PLIGHTS1, 20
|
152, 156, 160, 164, 168, // C_PLIGHTS1, 20
|
||||||
172, 176, 180, 184, 188, // C_PLIGHTS2, 20
|
172, 176, 180, 184, 188, // C_PLIGHTS2, 20
|
||||||
192, 196, 200, 204, 208, // C_PLIGHTS3, 20
|
192, 196, 200, 204, 208, // C_PLIGHTS3, 20
|
||||||
212, 216, 220, 224, 228, // C_PLIGHTS4, 20
|
212, 216, 220, 224, 228, // C_PLIGHTS4, 20
|
||||||
232, 236, 240, 244, 248, // C_PLIGHTS5, 20
|
232, 236, 240, 244, 248, // C_PLIGHTS5, 20
|
||||||
252, 256, 260, 264, 268, // C_PLIGHTS6, 20
|
252, 256, 260, 264, 268, // C_PLIGHTS6, 20
|
||||||
272, 276, 280, 284, 288, // C_PLIGHTS7, 20
|
272, 276, 280, 284, 288, // C_PLIGHTS7, 20
|
||||||
292, 296, 300, 304, // C_PMATERIALS, 16
|
292, 296, 300, 304, // C_PMATERIALS, 16
|
||||||
};
|
};
|
||||||
void PixelShaderCache::SetPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4)
|
void PixelShaderCache::SetPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4)
|
||||||
{
|
{
|
||||||
D3D::gfxstate->psconstants[ps_constant_offset_table[const_number] ] = f1;
|
D3D::gfxstate->psconstants[ps_constant_offset_table[const_number] ] = f1;
|
||||||
D3D::gfxstate->psconstants[ps_constant_offset_table[const_number]+1] = f2;
|
D3D::gfxstate->psconstants[ps_constant_offset_table[const_number]+1] = f2;
|
||||||
D3D::gfxstate->psconstants[ps_constant_offset_table[const_number]+2] = f3;
|
D3D::gfxstate->psconstants[ps_constant_offset_table[const_number]+2] = f3;
|
||||||
D3D::gfxstate->psconstants[ps_constant_offset_table[const_number]+3] = f4;
|
D3D::gfxstate->psconstants[ps_constant_offset_table[const_number]+3] = f4;
|
||||||
D3D::gfxstate->pscbufchanged = true;
|
D3D::gfxstate->pscbufchanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PixelShaderCache::SetPSConstant4fv(unsigned int const_number, const float* f)
|
void PixelShaderCache::SetPSConstant4fv(unsigned int const_number, const float* f)
|
||||||
{
|
{
|
||||||
memcpy(&D3D::gfxstate->psconstants[ps_constant_offset_table[const_number]], f, sizeof(float)*4);
|
memcpy(&D3D::gfxstate->psconstants[ps_constant_offset_table[const_number]], f, sizeof(float)*4);
|
||||||
D3D::gfxstate->pscbufchanged = true;
|
D3D::gfxstate->pscbufchanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PixelShaderCache::SetMultiPSConstant4fv(unsigned int const_number, unsigned int count, const float* f)
|
void PixelShaderCache::SetMultiPSConstant4fv(unsigned int const_number, unsigned int count, const float* f)
|
||||||
{
|
{
|
||||||
memcpy(&D3D::gfxstate->psconstants[ps_constant_offset_table[const_number]], f, sizeof(float)*4*count);
|
memcpy(&D3D::gfxstate->psconstants[ps_constant_offset_table[const_number]], f, sizeof(float)*4*count);
|
||||||
D3D::gfxstate->pscbufchanged = true;
|
D3D::gfxstate->pscbufchanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// this class will load the precompiled shaders into our cache
|
// this class will load the precompiled shaders into our cache
|
||||||
class PixelShaderCacheInserter : public LinearDiskCacheReader
|
class PixelShaderCacheInserter : public LinearDiskCacheReader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void Read(const u8* key, int key_size, const u8* value, int value_size)
|
void Read(const u8* key, int key_size, const u8* value, int value_size)
|
||||||
{
|
{
|
||||||
PIXELSHADERUID uid;
|
PIXELSHADERUID uid;
|
||||||
if (key_size != sizeof(uid)) {
|
if (key_size != sizeof(uid)) {
|
||||||
ERROR_LOG(VIDEO, "Wrong key size in pixel shader cache");
|
ERROR_LOG(VIDEO, "Wrong key size in pixel shader cache");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memcpy(&uid, key, key_size);
|
memcpy(&uid, key, key_size);
|
||||||
PixelShaderCache::InsertByteCode(uid, (void*)value, value_size);
|
PixelShaderCache::InsertByteCode(uid, (void*)value, value_size);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
PixelShaderCache::PixelShaderCache()
|
PixelShaderCache::PixelShaderCache()
|
||||||
{
|
{
|
||||||
// used when drawing clear quads
|
// used when drawing clear quads
|
||||||
s_ClearProgram = D3D::CompileAndCreatePixelShader(clear_program_code, sizeof(clear_program_code));
|
s_ClearProgram = D3D::CompileAndCreatePixelShader(clear_program_code, sizeof(clear_program_code));
|
||||||
CHECK(s_ClearProgram!=NULL, "Create clear pixel shader");
|
CHECK(s_ClearProgram!=NULL, "Create clear pixel shader");
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)s_ClearProgram, "clear pixel shader");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)s_ClearProgram, "clear pixel shader");
|
||||||
|
|
||||||
// used when copying/resolving the color buffer
|
// used when copying/resolving the color buffer
|
||||||
s_ColorCopyProgram = D3D::CompileAndCreatePixelShader(color_copy_program_code, sizeof(color_copy_program_code));
|
s_ColorCopyProgram = D3D::CompileAndCreatePixelShader(color_copy_program_code, sizeof(color_copy_program_code));
|
||||||
CHECK(s_ColorCopyProgram!=NULL, "Create color copy pixel shader");
|
CHECK(s_ColorCopyProgram!=NULL, "Create color copy pixel shader");
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)s_ClearProgram, "color copy pixel shader");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)s_ClearProgram, "color copy pixel shader");
|
||||||
|
|
||||||
// used for color conversion
|
// used for color conversion
|
||||||
s_ColorMatrixProgram = D3D::CompileAndCreatePixelShader(color_matrix_program_code, sizeof(color_matrix_program_code));
|
s_ColorMatrixProgram = D3D::CompileAndCreatePixelShader(color_matrix_program_code, sizeof(color_matrix_program_code));
|
||||||
CHECK(s_ColorMatrixProgram!=NULL, "Create color matrix pixel shader");
|
CHECK(s_ColorMatrixProgram!=NULL, "Create color matrix pixel shader");
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)s_ClearProgram, "color matrix pixel shader");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)s_ClearProgram, "color matrix pixel shader");
|
||||||
|
|
||||||
// used for depth copy
|
// used for depth copy
|
||||||
s_DepthMatrixProgram = D3D::CompileAndCreatePixelShader(depth_matrix_program, sizeof(depth_matrix_program));
|
s_DepthMatrixProgram = D3D::CompileAndCreatePixelShader(depth_matrix_program, sizeof(depth_matrix_program));
|
||||||
CHECK(s_DepthMatrixProgram!=NULL, "Create depth matrix pixel shader");
|
CHECK(s_DepthMatrixProgram!=NULL, "Create depth matrix pixel shader");
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)s_ClearProgram, "depth matrix pixel shader");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)s_ClearProgram, "depth matrix pixel shader");
|
||||||
|
|
||||||
Clear();
|
Clear();
|
||||||
|
|
||||||
if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX)))
|
if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX)))
|
||||||
File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX));
|
File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX));
|
||||||
|
|
||||||
char cache_filename[MAX_PATH];
|
char cache_filename[MAX_PATH];
|
||||||
sprintf(cache_filename, "%sdx11-%s-ps.cache", File::GetUserPath(D_SHADERCACHE_IDX), g_globals->unique_id);
|
sprintf(cache_filename, "%sdx11-%s-ps.cache", File::GetUserPath(D_SHADERCACHE_IDX), g_globals->unique_id);
|
||||||
PixelShaderCacheInserter inserter;
|
PixelShaderCacheInserter inserter;
|
||||||
g_ps_disk_cache.OpenAndRead(cache_filename, &inserter);
|
g_ps_disk_cache.OpenAndRead(cache_filename, &inserter);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ONLY to be used during shutdown.
|
// ONLY to be used during shutdown.
|
||||||
void PixelShaderCache::Clear()
|
void PixelShaderCache::Clear()
|
||||||
{
|
{
|
||||||
for (PSCache::iterator iter = PixelShaders.begin(); iter != PixelShaders.end(); iter++)
|
for (PSCache::iterator iter = PixelShaders.begin(); iter != PixelShaders.end(); iter++)
|
||||||
iter->second.Destroy();
|
iter->second.Destroy();
|
||||||
PixelShaders.clear();
|
PixelShaders.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
PixelShaderCache::~PixelShaderCache()
|
PixelShaderCache::~PixelShaderCache()
|
||||||
{
|
{
|
||||||
SAFE_RELEASE(s_ColorMatrixProgram);
|
SAFE_RELEASE(s_ColorMatrixProgram);
|
||||||
SAFE_RELEASE(s_ColorCopyProgram);
|
SAFE_RELEASE(s_ColorCopyProgram);
|
||||||
SAFE_RELEASE(s_DepthMatrixProgram);
|
SAFE_RELEASE(s_DepthMatrixProgram);
|
||||||
SAFE_RELEASE(s_ClearProgram);
|
SAFE_RELEASE(s_ClearProgram);
|
||||||
|
|
||||||
Clear();
|
Clear();
|
||||||
g_ps_disk_cache.Sync();
|
g_ps_disk_cache.Sync();
|
||||||
g_ps_disk_cache.Close();
|
g_ps_disk_cache.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PixelShaderCache::SetShader(bool dstAlpha)
|
bool PixelShaderCache::SetShader(bool dstAlpha)
|
||||||
{
|
{
|
||||||
PIXELSHADERUID uid;
|
PIXELSHADERUID uid;
|
||||||
GetPixelShaderId(&uid, dstAlpha);
|
GetPixelShaderId(&uid, dstAlpha);
|
||||||
|
|
||||||
// check if the shader is already set
|
// check if the shader is already set
|
||||||
if (uid == last_pixel_shader_uid && PixelShaders[uid].frameCount == frameCount)
|
if (uid == last_pixel_shader_uid && PixelShaders[uid].frameCount == frameCount)
|
||||||
{
|
{
|
||||||
PSCache::const_iterator iter = PixelShaders.find(uid);
|
PSCache::const_iterator iter = PixelShaders.find(uid);
|
||||||
return (iter != PixelShaders.end() && iter->second.shader);
|
return (iter != PixelShaders.end() && iter->second.shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(&last_pixel_shader_uid, &uid, sizeof(PIXELSHADERUID));
|
memcpy(&last_pixel_shader_uid, &uid, sizeof(PIXELSHADERUID));
|
||||||
|
|
||||||
// check if the shader is already in the cache
|
// check if the shader is already in the cache
|
||||||
PSCache::iterator iter = PixelShaders.find(uid);
|
PSCache::iterator iter = PixelShaders.find(uid);
|
||||||
if (iter != PixelShaders.end())
|
if (iter != PixelShaders.end())
|
||||||
{
|
{
|
||||||
iter->second.frameCount = frameCount;
|
iter->second.frameCount = frameCount;
|
||||||
const PSCacheEntry &entry = iter->second;
|
const PSCacheEntry &entry = iter->second;
|
||||||
last_entry = &entry;
|
last_entry = &entry;
|
||||||
|
|
||||||
D3D::gfxstate->SetPShader(entry.shader);
|
D3D::gfxstate->SetPShader(entry.shader);
|
||||||
return (entry.shader != NULL);
|
return (entry.shader != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// need to compile a new shader
|
// need to compile a new shader
|
||||||
const char* code = GeneratePixelShaderCode(dstAlpha, API_D3D11);
|
const char* code = GeneratePixelShaderCode(dstAlpha, API_D3D11);
|
||||||
|
|
||||||
D3DBlob* pbytecode;
|
D3DBlob* pbytecode;
|
||||||
if (!D3D::CompilePixelShader(code, (unsigned int)strlen(code), &pbytecode))
|
if (!D3D::CompilePixelShader(code, (unsigned int)strlen(code), &pbytecode))
|
||||||
{
|
{
|
||||||
PanicAlert("Failed to compile Pixel Shader:\n\n%s", code);
|
PanicAlert("Failed to compile Pixel Shader:\n\n%s", code);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// insert the bytecode into the caches
|
// insert the bytecode into the caches
|
||||||
g_ps_disk_cache.Append((u8*)&uid, sizeof(uid), (const u8*)pbytecode->Data(), pbytecode->Size());
|
g_ps_disk_cache.Append((u8*)&uid, sizeof(uid), (const u8*)pbytecode->Data(), pbytecode->Size());
|
||||||
g_ps_disk_cache.Sync();
|
g_ps_disk_cache.Sync();
|
||||||
|
|
||||||
bool result = InsertByteCode(uid, pbytecode->Data(), pbytecode->Size());
|
bool result = InsertByteCode(uid, pbytecode->Data(), pbytecode->Size());
|
||||||
D3D::gfxstate->SetPShader(last_entry->shader);
|
D3D::gfxstate->SetPShader(last_entry->shader);
|
||||||
pbytecode->Release();
|
pbytecode->Release();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PixelShaderCache::InsertByteCode(const PIXELSHADERUID &uid, void* bytecode, unsigned int bytecodelen)
|
bool PixelShaderCache::InsertByteCode(const PIXELSHADERUID &uid, void* bytecode, unsigned int bytecodelen)
|
||||||
{
|
{
|
||||||
ID3D11PixelShader* shader = D3D::CreatePixelShaderFromByteCode(bytecode, bytecodelen);
|
ID3D11PixelShader* shader = D3D::CreatePixelShaderFromByteCode(bytecode, bytecodelen);
|
||||||
if (shader == NULL)
|
if (shader == NULL)
|
||||||
{
|
{
|
||||||
PanicAlert("Failed to create pixel shader at %s %d\n", __FILE__, __LINE__);
|
PanicAlert("Failed to create pixel shader at %s %d\n", __FILE__, __LINE__);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// TODO: Somehow make the debug name a bit more specific
|
// TODO: Somehow make the debug name a bit more specific
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)shader, "a pixel shader of PixelShaderCache");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)shader, "a pixel shader of PixelShaderCache");
|
||||||
|
|
||||||
// make an entry in the table
|
// make an entry in the table
|
||||||
PSCacheEntry newentry;
|
PSCacheEntry newentry;
|
||||||
newentry.shader = shader;
|
newentry.shader = shader;
|
||||||
newentry.frameCount = frameCount;
|
newentry.frameCount = frameCount;
|
||||||
PixelShaders[uid] = newentry;
|
PixelShaders[uid] = newentry;
|
||||||
last_entry = &PixelShaders[uid];
|
last_entry = &PixelShaders[uid];
|
||||||
|
|
||||||
INCSTAT(stats.numPixelShadersCreated);
|
INCSTAT(stats.numPixelShadersCreated);
|
||||||
SETSTAT(stats.numPixelShadersAlive, PixelShaders.size());
|
SETSTAT(stats.numPixelShadersAlive, PixelShaders.size());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,74 +1,74 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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
|
#pragma once
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
// Common
|
// Common
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "LinearDiskCache.h"
|
#include "LinearDiskCache.h"
|
||||||
|
|
||||||
// VideoCommon
|
// VideoCommon
|
||||||
#include "PixelShaderGen.h"
|
#include "PixelShaderGen.h"
|
||||||
#include "VertexShaderGen.h"
|
#include "VertexShaderGen.h"
|
||||||
|
|
||||||
// DX11
|
// DX11
|
||||||
#include "DX11_D3DBase.h"
|
#include "DX11_D3DBase.h"
|
||||||
|
|
||||||
#include "../PixelShaderCache.h"
|
#include "../PixelShaderCache.h"
|
||||||
|
|
||||||
namespace DX11
|
namespace DX11
|
||||||
{
|
{
|
||||||
|
|
||||||
class PixelShaderCache : public ::PixelShaderCacheBase
|
class PixelShaderCache : public ::PixelShaderCacheBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PixelShaderCache();
|
PixelShaderCache();
|
||||||
~PixelShaderCache();
|
~PixelShaderCache();
|
||||||
|
|
||||||
void Clear();
|
void Clear();
|
||||||
|
|
||||||
bool SetShader(bool dstAlpha);
|
bool SetShader(bool dstAlpha);
|
||||||
static bool InsertByteCode(const PIXELSHADERUID &uid, void* bytecode, unsigned int bytecodelen);
|
static bool InsertByteCode(const PIXELSHADERUID &uid, void* bytecode, unsigned int bytecodelen);
|
||||||
|
|
||||||
static ID3D11PixelShader* GetColorMatrixProgram();
|
static ID3D11PixelShader* GetColorMatrixProgram();
|
||||||
static ID3D11PixelShader* GetColorCopyProgram();
|
static ID3D11PixelShader* GetColorCopyProgram();
|
||||||
static ID3D11PixelShader* GetDepthMatrixProgram();
|
static ID3D11PixelShader* GetDepthMatrixProgram();
|
||||||
static ID3D11PixelShader* GetClearProgram();
|
static ID3D11PixelShader* GetClearProgram();
|
||||||
|
|
||||||
void SetPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4);
|
void SetPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4);
|
||||||
void SetPSConstant4fv(unsigned int const_number, const float *f);
|
void SetPSConstant4fv(unsigned int const_number, const float *f);
|
||||||
void SetMultiPSConstant4fv(unsigned int const_number, unsigned int count, const float *f);
|
void SetMultiPSConstant4fv(unsigned int const_number, unsigned int count, const float *f);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct PSCacheEntry
|
struct PSCacheEntry
|
||||||
{
|
{
|
||||||
ID3D11PixelShader* shader;
|
ID3D11PixelShader* shader;
|
||||||
int frameCount;
|
int frameCount;
|
||||||
|
|
||||||
PSCacheEntry() : shader(NULL), frameCount(0) {}
|
PSCacheEntry() : shader(NULL), frameCount(0) {}
|
||||||
void Destroy() { SAFE_RELEASE(shader); }
|
void Destroy() { SAFE_RELEASE(shader); }
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<PIXELSHADERUID, PSCacheEntry> PSCache;
|
typedef std::map<PIXELSHADERUID, PSCacheEntry> PSCache;
|
||||||
|
|
||||||
static PSCache PixelShaders;
|
static PSCache PixelShaders;
|
||||||
static const PSCacheEntry* last_entry;
|
static const PSCacheEntry* last_entry;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,52 +1,52 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "MathUtil.h"
|
#include "MathUtil.h"
|
||||||
|
|
||||||
#include "VideoCommon.h"
|
#include "VideoCommon.h"
|
||||||
#include "Renderer.h"
|
#include "Renderer.h"
|
||||||
#include "pluginspecs_video.h"
|
#include "pluginspecs_video.h"
|
||||||
|
|
||||||
namespace DX11
|
namespace DX11
|
||||||
{
|
{
|
||||||
|
|
||||||
class Renderer : public ::RendererBase
|
class Renderer : public ::RendererBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Renderer();
|
Renderer();
|
||||||
~Renderer();
|
~Renderer();
|
||||||
|
|
||||||
// What's the real difference between these? Too similar names.
|
// What's the real difference between these? Too similar names.
|
||||||
void ResetAPIState();
|
void ResetAPIState();
|
||||||
void RestoreAPIState();
|
void RestoreAPIState();
|
||||||
|
|
||||||
static void SetupDeviceObjects();
|
static void SetupDeviceObjects();
|
||||||
static void TeardownDeviceObjects();
|
static void TeardownDeviceObjects();
|
||||||
|
|
||||||
void SetColorMask();
|
void SetColorMask();
|
||||||
void SetBlendMode(bool forceUpdate);
|
void SetBlendMode(bool forceUpdate);
|
||||||
bool SetScissorRect();
|
bool SetScissorRect();
|
||||||
|
|
||||||
void SetGenerationMode();
|
void SetGenerationMode();
|
||||||
void SetDepthMode();
|
void SetDepthMode();
|
||||||
void SetLogicOpMode();
|
void SetLogicOpMode();
|
||||||
void SetSamplerState(int stage,int texindex);
|
void SetSamplerState(int stage,int texindex);
|
||||||
|
|
||||||
u32 AccessEFB(EFBAccessType type, int x, int y);
|
u32 AccessEFB(EFBAccessType type, int x, int y);
|
||||||
|
|
||||||
void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z);
|
void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z);
|
||||||
void UpdateViewport();
|
void UpdateViewport();
|
||||||
|
|
||||||
// virtual funcs used by RendererBase::Swap
|
// virtual funcs used by RendererBase::Swap
|
||||||
void PrepareXFBCopy(const TargetRectangle &dst_rect);
|
void PrepareXFBCopy(const TargetRectangle &dst_rect);
|
||||||
void Draw(const XFBSourceBase* xfbSource, const TargetRectangle& sourceRc,
|
void Draw(const XFBSourceBase* xfbSource, const TargetRectangle& sourceRc,
|
||||||
const MathUtil::Rectangle<float>& drawRc, const EFBRectangle& rc);
|
const MathUtil::Rectangle<float>& drawRc, const EFBRectangle& rc);
|
||||||
void EndFrame();
|
void EndFrame();
|
||||||
void Present();
|
void Present();
|
||||||
bool CheckForResize();
|
bool CheckForResize();
|
||||||
void GetBackBufferSize(int* w, int* h);
|
void GetBackBufferSize(int* w, int* h);
|
||||||
void RecreateFramebufferManger();
|
void RecreateFramebufferManger();
|
||||||
void BeginFrame();
|
void BeginFrame();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,230 +1,230 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
#include <d3dx11.h>
|
#include <d3dx11.h>
|
||||||
|
|
||||||
// Common
|
// Common
|
||||||
#include "CommonPaths.h"
|
#include "CommonPaths.h"
|
||||||
#include "FileUtil.h"
|
#include "FileUtil.h"
|
||||||
#include "MemoryUtil.h"
|
#include "MemoryUtil.h"
|
||||||
#include "Hash.h"
|
#include "Hash.h"
|
||||||
|
|
||||||
// VideoCommon
|
// VideoCommon
|
||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
#include "Statistics.h"
|
#include "Statistics.h"
|
||||||
#include "PixelShaderManager.h"
|
#include "PixelShaderManager.h"
|
||||||
#include "VertexShaderManager.h"
|
#include "VertexShaderManager.h"
|
||||||
#include "TextureDecoder.h"
|
#include "TextureDecoder.h"
|
||||||
#include "HiresTextures.h"
|
#include "HiresTextures.h"
|
||||||
|
|
||||||
// DX11
|
// DX11
|
||||||
#include "DX11_D3DBase.h"
|
#include "DX11_D3DBase.h"
|
||||||
#include "DX11_D3DTexture.h"
|
#include "DX11_D3DTexture.h"
|
||||||
#include "DX11_D3DUtil.h"
|
#include "DX11_D3DUtil.h"
|
||||||
#include "DX11_FramebufferManager.h"
|
#include "DX11_FramebufferManager.h"
|
||||||
#include "DX11_PixelShaderCache.h"
|
#include "DX11_PixelShaderCache.h"
|
||||||
#include "DX11_VertexShaderCache.h"
|
#include "DX11_VertexShaderCache.h"
|
||||||
#include "DX11_TextureCache.h"
|
#include "DX11_TextureCache.h"
|
||||||
|
|
||||||
#include "../Main.h"
|
#include "../Main.h"
|
||||||
|
|
||||||
namespace DX11
|
namespace DX11
|
||||||
{
|
{
|
||||||
|
|
||||||
ID3D11BlendState* efbcopyblendstate = NULL;
|
ID3D11BlendState* efbcopyblendstate = NULL;
|
||||||
ID3D11RasterizerState* efbcopyraststate = NULL;
|
ID3D11RasterizerState* efbcopyraststate = NULL;
|
||||||
ID3D11DepthStencilState* efbcopydepthstate = NULL;
|
ID3D11DepthStencilState* efbcopydepthstate = NULL;
|
||||||
ID3D11Buffer* efbcopycbuf[20] = {};
|
ID3D11Buffer* efbcopycbuf[20] = {};
|
||||||
|
|
||||||
TextureCache::TCacheEntry::~TCacheEntry()
|
TextureCache::TCacheEntry::~TCacheEntry()
|
||||||
{
|
{
|
||||||
SAFE_RELEASE(texture);
|
SAFE_RELEASE(texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCache::TCacheEntry::Load(unsigned int width, unsigned int height,
|
void TextureCache::TCacheEntry::Load(unsigned int width, unsigned int height,
|
||||||
unsigned int expanded_width, unsigned int level)
|
unsigned int expanded_width, unsigned int level)
|
||||||
{
|
{
|
||||||
D3D::ReplaceRGBATexture2D(texture->GetTex(), TextureCache::temp, width, height, expanded_width, level, usage);
|
D3D::ReplaceRGBATexture2D(texture->GetTex(), TextureCache::temp, width, height, expanded_width, level, usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleByHalf,
|
void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleByHalf,
|
||||||
unsigned int cbufid, const float colmat[], const EFBRectangle &source_rect)
|
unsigned int cbufid, const float colmat[], const EFBRectangle &source_rect)
|
||||||
{
|
{
|
||||||
// stretch picture with increased internal resolution
|
// stretch picture with increased internal resolution
|
||||||
const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)Scaledw, (float)Scaledh);
|
const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)Scaledw, (float)Scaledh);
|
||||||
D3D::context->RSSetViewports(1, &vp);
|
D3D::context->RSSetViewports(1, &vp);
|
||||||
|
|
||||||
// set transformation
|
// set transformation
|
||||||
if (NULL == efbcopycbuf[cbufid])
|
if (NULL == efbcopycbuf[cbufid])
|
||||||
{
|
{
|
||||||
const D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(20 * sizeof(float), D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DEFAULT);
|
const D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(20 * sizeof(float), D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DEFAULT);
|
||||||
D3D11_SUBRESOURCE_DATA data;
|
D3D11_SUBRESOURCE_DATA data;
|
||||||
data.pSysMem = colmat;
|
data.pSysMem = colmat;
|
||||||
HRESULT hr = D3D::device->CreateBuffer(&cbdesc, &data, &efbcopycbuf[cbufid]);
|
HRESULT hr = D3D::device->CreateBuffer(&cbdesc, &data, &efbcopycbuf[cbufid]);
|
||||||
CHECK(SUCCEEDED(hr), "Create efb copy constant buffer %d", cbufid);
|
CHECK(SUCCEEDED(hr), "Create efb copy constant buffer %d", cbufid);
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)efbcopycbuf[cbufid], "a constant buffer used in TextureCache::CopyRenderTargetToTexture");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)efbcopycbuf[cbufid], "a constant buffer used in TextureCache::CopyRenderTargetToTexture");
|
||||||
}
|
}
|
||||||
D3D::context->PSSetConstantBuffers(0, 1, &efbcopycbuf[cbufid]);
|
D3D::context->PSSetConstantBuffers(0, 1, &efbcopycbuf[cbufid]);
|
||||||
|
|
||||||
const TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(source_rect);
|
const TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(source_rect);
|
||||||
// TODO: try targetSource.asRECT();
|
// TODO: try targetSource.asRECT();
|
||||||
const D3D11_RECT sourcerect = CD3D11_RECT(targetSource.left, targetSource.top, targetSource.right, targetSource.bottom);
|
const D3D11_RECT sourcerect = CD3D11_RECT(targetSource.left, targetSource.top, targetSource.right, targetSource.bottom);
|
||||||
|
|
||||||
// Use linear filtering if (bScaleByHalf), use point filtering otherwise
|
// Use linear filtering if (bScaleByHalf), use point filtering otherwise
|
||||||
if (bScaleByHalf)
|
if (bScaleByHalf)
|
||||||
D3D::SetLinearCopySampler();
|
D3D::SetLinearCopySampler();
|
||||||
else
|
else
|
||||||
D3D::SetPointCopySampler();
|
D3D::SetPointCopySampler();
|
||||||
|
|
||||||
D3D::stateman->PushBlendState(efbcopyblendstate);
|
D3D::stateman->PushBlendState(efbcopyblendstate);
|
||||||
D3D::stateman->PushRasterizerState(efbcopyraststate);
|
D3D::stateman->PushRasterizerState(efbcopyraststate);
|
||||||
D3D::stateman->PushDepthState(efbcopydepthstate);
|
D3D::stateman->PushDepthState(efbcopydepthstate);
|
||||||
|
|
||||||
D3D::context->OMSetRenderTargets(1, &texture->GetRTV(), NULL);
|
D3D::context->OMSetRenderTargets(1, &texture->GetRTV(), NULL);
|
||||||
|
|
||||||
D3D::drawShadedTexQuad(
|
D3D::drawShadedTexQuad(
|
||||||
(bFromZBuffer) ? FramebufferManager::GetEFBDepthTexture()->GetSRV() : FramebufferManager::GetEFBColorTexture()->GetSRV(),
|
(bFromZBuffer) ? FramebufferManager::GetEFBDepthTexture()->GetSRV() : FramebufferManager::GetEFBColorTexture()->GetSRV(),
|
||||||
&sourcerect, g_renderer->GetFullTargetWidth(), g_renderer->GetFullTargetHeight(),
|
&sourcerect, g_renderer->GetFullTargetWidth(), g_renderer->GetFullTargetHeight(),
|
||||||
(bFromZBuffer) ? PixelShaderCache::GetDepthMatrixProgram() : PixelShaderCache::GetColorMatrixProgram(),
|
(bFromZBuffer) ? PixelShaderCache::GetDepthMatrixProgram() : PixelShaderCache::GetColorMatrixProgram(),
|
||||||
VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout());
|
VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout());
|
||||||
|
|
||||||
D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV());
|
D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV());
|
||||||
|
|
||||||
D3D::stateman->PopBlendState();
|
D3D::stateman->PopBlendState();
|
||||||
D3D::stateman->PopDepthState();
|
D3D::stateman->PopDepthState();
|
||||||
D3D::stateman->PopRasterizerState();
|
D3D::stateman->PopRasterizerState();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCache::TCacheEntry::Bind(unsigned int stage)
|
void TextureCache::TCacheEntry::Bind(unsigned int stage)
|
||||||
{
|
{
|
||||||
D3D::gfxstate->SetShaderResource(stage, texture->GetSRV());
|
D3D::gfxstate->SetShaderResource(stage, texture->GetSRV());
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureCache::TCacheEntryBase* TextureCache::CreateTexture(unsigned int width,
|
TextureCache::TCacheEntryBase* TextureCache::CreateTexture(unsigned int width,
|
||||||
unsigned int height, unsigned int expanded_width,
|
unsigned int height, unsigned int expanded_width,
|
||||||
unsigned int tex_levels, PC_TexFormat pcfmt)
|
unsigned int tex_levels, PC_TexFormat pcfmt)
|
||||||
{
|
{
|
||||||
D3D11_SUBRESOURCE_DATA srdata;
|
D3D11_SUBRESOURCE_DATA srdata;
|
||||||
|
|
||||||
D3D11_SUBRESOURCE_DATA *data = NULL;
|
D3D11_SUBRESOURCE_DATA *data = NULL;
|
||||||
D3D11_CPU_ACCESS_FLAG cpu_access = (D3D11_CPU_ACCESS_FLAG)0;
|
D3D11_CPU_ACCESS_FLAG cpu_access = (D3D11_CPU_ACCESS_FLAG)0;
|
||||||
D3D11_USAGE usage = D3D11_USAGE_DEFAULT;
|
D3D11_USAGE usage = D3D11_USAGE_DEFAULT;
|
||||||
|
|
||||||
// TODO: temp
|
// TODO: temp
|
||||||
tex_levels = 1;
|
tex_levels = 1;
|
||||||
|
|
||||||
if (1 == tex_levels)
|
if (1 == tex_levels)
|
||||||
{
|
{
|
||||||
cpu_access = D3D11_CPU_ACCESS_WRITE;
|
cpu_access = D3D11_CPU_ACCESS_WRITE;
|
||||||
usage = D3D11_USAGE_DYNAMIC;
|
usage = D3D11_USAGE_DYNAMIC;
|
||||||
|
|
||||||
srdata.pSysMem = temp;
|
srdata.pSysMem = temp;
|
||||||
srdata.SysMemPitch = 4 * expanded_width;
|
srdata.SysMemPitch = 4 * expanded_width;
|
||||||
data = &srdata;
|
data = &srdata;
|
||||||
}
|
}
|
||||||
|
|
||||||
const D3D11_TEXTURE2D_DESC texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM,
|
const D3D11_TEXTURE2D_DESC texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM,
|
||||||
width, height, 1, tex_levels, D3D11_BIND_SHADER_RESOURCE, usage, cpu_access);
|
width, height, 1, tex_levels, D3D11_BIND_SHADER_RESOURCE, usage, cpu_access);
|
||||||
|
|
||||||
ID3D11Texture2D *pTexture;
|
ID3D11Texture2D *pTexture;
|
||||||
HRESULT hr = D3D::device->CreateTexture2D(&texdesc, data, &pTexture);
|
HRESULT hr = D3D::device->CreateTexture2D(&texdesc, data, &pTexture);
|
||||||
CHECK(SUCCEEDED(hr), "Create texture of the TextureCache");
|
CHECK(SUCCEEDED(hr), "Create texture of the TextureCache");
|
||||||
|
|
||||||
TCacheEntry* const entry = new TCacheEntry(new D3DTexture2D(pTexture, D3D11_BIND_SHADER_RESOURCE));
|
TCacheEntry* const entry = new TCacheEntry(new D3DTexture2D(pTexture, D3D11_BIND_SHADER_RESOURCE));
|
||||||
entry->usage = usage;
|
entry->usage = usage;
|
||||||
|
|
||||||
// TODO: silly debug names
|
// TODO: silly debug names
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)entry->texture->GetTex(), "a texture of the TextureCache");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)entry->texture->GetTex(), "a texture of the TextureCache");
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)entry->texture->GetSRV(), "shader resource view of a texture of the TextureCache");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)entry->texture->GetSRV(), "shader resource view of a texture of the TextureCache");
|
||||||
|
|
||||||
// wuts this?
|
// wuts this?
|
||||||
//if (0 == tex_levels)
|
//if (0 == tex_levels)
|
||||||
// PD3DX11FilterTexture(D3D::context, entry->texture->GetTex(), 0, D3DX11_DEFAULT);
|
// PD3DX11FilterTexture(D3D::context, entry->texture->GetTex(), 0, D3DX11_DEFAULT);
|
||||||
|
|
||||||
// TODO: this good?
|
// TODO: this good?
|
||||||
//if (1 != tex_levels)
|
//if (1 != tex_levels)
|
||||||
// entry->Load(width, height, expanded_width, 0);
|
// entry->Load(width, height, expanded_width, 0);
|
||||||
|
|
||||||
SAFE_RELEASE(pTexture);
|
SAFE_RELEASE(pTexture);
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureCache::TCacheEntryBase* TextureCache::CreateRenderTargetTexture(int scaled_tex_w, int scaled_tex_h)
|
TextureCache::TCacheEntryBase* TextureCache::CreateRenderTargetTexture(int scaled_tex_w, int scaled_tex_h)
|
||||||
{
|
{
|
||||||
return new TCacheEntry(D3DTexture2D::Create(scaled_tex_w, scaled_tex_h,
|
return new TCacheEntry(D3DTexture2D::Create(scaled_tex_w, scaled_tex_h,
|
||||||
(D3D11_BIND_FLAG)((int)D3D11_BIND_RENDER_TARGET | (int)D3D11_BIND_SHADER_RESOURCE),
|
(D3D11_BIND_FLAG)((int)D3D11_BIND_RENDER_TARGET | (int)D3D11_BIND_SHADER_RESOURCE),
|
||||||
D3D11_USAGE_DEFAULT, DXGI_FORMAT_R8G8B8A8_UNORM));
|
D3D11_USAGE_DEFAULT, DXGI_FORMAT_R8G8B8A8_UNORM));
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureCache::TextureCache()
|
TextureCache::TextureCache()
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
D3D11_BLEND_DESC blenddesc;
|
D3D11_BLEND_DESC blenddesc;
|
||||||
blenddesc.AlphaToCoverageEnable = FALSE;
|
blenddesc.AlphaToCoverageEnable = FALSE;
|
||||||
blenddesc.IndependentBlendEnable = FALSE;
|
blenddesc.IndependentBlendEnable = FALSE;
|
||||||
blenddesc.RenderTarget[0].BlendEnable = FALSE;
|
blenddesc.RenderTarget[0].BlendEnable = FALSE;
|
||||||
blenddesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
|
blenddesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
|
||||||
blenddesc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE;
|
blenddesc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE;
|
||||||
blenddesc.RenderTarget[0].DestBlend = D3D11_BLEND_ZERO;
|
blenddesc.RenderTarget[0].DestBlend = D3D11_BLEND_ZERO;
|
||||||
blenddesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
|
blenddesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
|
||||||
blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
|
blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
|
||||||
blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
|
blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
|
||||||
blenddesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
|
blenddesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
|
||||||
hr = D3D::device->CreateBlendState(&blenddesc, &efbcopyblendstate);
|
hr = D3D::device->CreateBlendState(&blenddesc, &efbcopyblendstate);
|
||||||
CHECK(hr==S_OK, "Create blend state for CopyRenderTargetToTexture");
|
CHECK(hr==S_OK, "Create blend state for CopyRenderTargetToTexture");
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)efbcopyblendstate, "blend state used in CopyRenderTargetToTexture");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)efbcopyblendstate, "blend state used in CopyRenderTargetToTexture");
|
||||||
|
|
||||||
D3D11_DEPTH_STENCIL_DESC depthdesc;
|
D3D11_DEPTH_STENCIL_DESC depthdesc;
|
||||||
depthdesc.DepthEnable = FALSE;
|
depthdesc.DepthEnable = FALSE;
|
||||||
depthdesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
|
depthdesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
|
||||||
depthdesc.DepthFunc = D3D11_COMPARISON_LESS;
|
depthdesc.DepthFunc = D3D11_COMPARISON_LESS;
|
||||||
depthdesc.StencilEnable = FALSE;
|
depthdesc.StencilEnable = FALSE;
|
||||||
depthdesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK;
|
depthdesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK;
|
||||||
depthdesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;
|
depthdesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;
|
||||||
hr = D3D::device->CreateDepthStencilState(&depthdesc, &efbcopydepthstate);
|
hr = D3D::device->CreateDepthStencilState(&depthdesc, &efbcopydepthstate);
|
||||||
CHECK(hr==S_OK, "Create depth state for CopyRenderTargetToTexture");
|
CHECK(hr==S_OK, "Create depth state for CopyRenderTargetToTexture");
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)efbcopydepthstate, "depth stencil state used in CopyRenderTargetToTexture");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)efbcopydepthstate, "depth stencil state used in CopyRenderTargetToTexture");
|
||||||
|
|
||||||
D3D11_RASTERIZER_DESC rastdesc;
|
D3D11_RASTERIZER_DESC rastdesc;
|
||||||
rastdesc.CullMode = D3D11_CULL_NONE;
|
rastdesc.CullMode = D3D11_CULL_NONE;
|
||||||
rastdesc.FillMode = D3D11_FILL_SOLID;
|
rastdesc.FillMode = D3D11_FILL_SOLID;
|
||||||
rastdesc.FrontCounterClockwise = false;
|
rastdesc.FrontCounterClockwise = false;
|
||||||
rastdesc.DepthBias = false;
|
rastdesc.DepthBias = false;
|
||||||
rastdesc.DepthBiasClamp = 0;
|
rastdesc.DepthBiasClamp = 0;
|
||||||
rastdesc.SlopeScaledDepthBias = 0;
|
rastdesc.SlopeScaledDepthBias = 0;
|
||||||
rastdesc.DepthClipEnable = false;
|
rastdesc.DepthClipEnable = false;
|
||||||
rastdesc.ScissorEnable = false;
|
rastdesc.ScissorEnable = false;
|
||||||
rastdesc.MultisampleEnable = false;
|
rastdesc.MultisampleEnable = false;
|
||||||
rastdesc.AntialiasedLineEnable = false;
|
rastdesc.AntialiasedLineEnable = false;
|
||||||
hr = D3D::device->CreateRasterizerState(&rastdesc, &efbcopyraststate);
|
hr = D3D::device->CreateRasterizerState(&rastdesc, &efbcopyraststate);
|
||||||
CHECK(hr==S_OK, "Create rasterizer state for CopyRenderTargetToTexture");
|
CHECK(hr==S_OK, "Create rasterizer state for CopyRenderTargetToTexture");
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)efbcopyraststate, "rasterizer state used in CopyRenderTargetToTexture");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)efbcopyraststate, "rasterizer state used in CopyRenderTargetToTexture");
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureCache::~TextureCache()
|
TextureCache::~TextureCache()
|
||||||
{
|
{
|
||||||
SAFE_RELEASE(efbcopyblendstate);
|
SAFE_RELEASE(efbcopyblendstate);
|
||||||
SAFE_RELEASE(efbcopyraststate);
|
SAFE_RELEASE(efbcopyraststate);
|
||||||
SAFE_RELEASE(efbcopydepthstate);
|
SAFE_RELEASE(efbcopydepthstate);
|
||||||
|
|
||||||
for (unsigned int k = 0; k < 20; ++k)
|
for (unsigned int k = 0; k < 20; ++k)
|
||||||
SAFE_RELEASE(efbcopycbuf[k]);
|
SAFE_RELEASE(efbcopycbuf[k]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,66 +1,66 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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
|
#pragma once
|
||||||
|
|
||||||
// VideoCommon
|
// VideoCommon
|
||||||
#include "VideoCommon.h"
|
#include "VideoCommon.h"
|
||||||
#include "BPMemory.h"
|
#include "BPMemory.h"
|
||||||
|
|
||||||
// DX11
|
// DX11
|
||||||
#include "DX11_D3DBase.h"
|
#include "DX11_D3DBase.h"
|
||||||
#include "DX11_D3DTexture.h"
|
#include "DX11_D3DTexture.h"
|
||||||
|
|
||||||
#include "../TextureCache.h"
|
#include "../TextureCache.h"
|
||||||
|
|
||||||
namespace DX11
|
namespace DX11
|
||||||
{
|
{
|
||||||
|
|
||||||
class TextureCache : public ::TextureCacheBase
|
class TextureCache : public ::TextureCacheBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
struct TCacheEntry : TCacheEntryBase
|
struct TCacheEntry : TCacheEntryBase
|
||||||
{
|
{
|
||||||
D3DTexture2D* texture;
|
D3DTexture2D* texture;
|
||||||
|
|
||||||
D3D11_USAGE usage;
|
D3D11_USAGE usage;
|
||||||
|
|
||||||
TCacheEntry(D3DTexture2D* _texture) : texture(_texture) {}
|
TCacheEntry(D3DTexture2D* _texture) : texture(_texture) {}
|
||||||
~TCacheEntry();
|
~TCacheEntry();
|
||||||
|
|
||||||
void Load(unsigned int width, unsigned int height,
|
void Load(unsigned int width, unsigned int height,
|
||||||
unsigned int expanded_width, unsigned int level);
|
unsigned int expanded_width, unsigned int level);
|
||||||
|
|
||||||
void FromRenderTarget(bool bFromZBuffer, bool bScaleByHalf,
|
void FromRenderTarget(bool bFromZBuffer, bool bScaleByHalf,
|
||||||
unsigned int cbufid, const float colmat[], const EFBRectangle &source_rect);
|
unsigned int cbufid, const float colmat[], const EFBRectangle &source_rect);
|
||||||
|
|
||||||
void Bind(unsigned int stage);
|
void Bind(unsigned int stage);
|
||||||
};
|
};
|
||||||
|
|
||||||
TextureCache();
|
TextureCache();
|
||||||
~TextureCache();
|
~TextureCache();
|
||||||
|
|
||||||
TCacheEntryBase* CreateTexture(unsigned int width, unsigned int height,
|
TCacheEntryBase* CreateTexture(unsigned int width, unsigned int height,
|
||||||
unsigned int expanded_width, unsigned int tex_levels, PC_TexFormat pcfmt);
|
unsigned int expanded_width, unsigned int tex_levels, PC_TexFormat pcfmt);
|
||||||
|
|
||||||
TCacheEntryBase* CreateRenderTargetTexture(int scaled_tex_w, int scaled_tex_h);
|
TCacheEntryBase* CreateRenderTargetTexture(int scaled_tex_w, int scaled_tex_h);
|
||||||
|
|
||||||
void CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, unsigned int bScaleByHalf, const EFBRectangle &source_rect);
|
void CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, unsigned int bScaleByHalf, const EFBRectangle &source_rect);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,194 +1,194 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
// Common
|
// Common
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "FileUtil.h"
|
#include "FileUtil.h"
|
||||||
|
|
||||||
// VideoCommon
|
// VideoCommon
|
||||||
#include "BPStructs.h"
|
#include "BPStructs.h"
|
||||||
#include "XFStructs.h"
|
#include "XFStructs.h"
|
||||||
#include "Fifo.h"
|
#include "Fifo.h"
|
||||||
#include "Statistics.h"
|
#include "Statistics.h"
|
||||||
#include "Profiler.h"
|
#include "Profiler.h"
|
||||||
#include "OpcodeDecoding.h"
|
#include "OpcodeDecoding.h"
|
||||||
#include "IndexGenerator.h"
|
#include "IndexGenerator.h"
|
||||||
#include "VertexShaderManager.h"
|
#include "VertexShaderManager.h"
|
||||||
#include "PixelShaderManager.h"
|
#include "PixelShaderManager.h"
|
||||||
#include "NativeVertexFormat.h"
|
#include "NativeVertexFormat.h"
|
||||||
#include "NativeVertexWriter.h"
|
#include "NativeVertexWriter.h"
|
||||||
|
|
||||||
// DX11
|
// DX11
|
||||||
#include "DX11_D3DBase.h"
|
#include "DX11_D3DBase.h"
|
||||||
#include "DX11_D3DShader.h"
|
#include "DX11_D3DShader.h"
|
||||||
#include "DX11_D3DUtil.h"
|
#include "DX11_D3DUtil.h"
|
||||||
#include "DX11_VertexManager.h"
|
#include "DX11_VertexManager.h"
|
||||||
#include "DX11_VertexShaderCache.h"
|
#include "DX11_VertexShaderCache.h"
|
||||||
#include "DX11_PixelShaderCache.h"
|
#include "DX11_PixelShaderCache.h"
|
||||||
#include "DX11_TextureCache.h"
|
#include "DX11_TextureCache.h"
|
||||||
#include "DX11_FramebufferManager.h"
|
#include "DX11_FramebufferManager.h"
|
||||||
#include "DX11_Render.h"
|
#include "DX11_Render.h"
|
||||||
|
|
||||||
#include "../Main.h"
|
#include "../Main.h"
|
||||||
|
|
||||||
//using std::string;
|
//using std::string;
|
||||||
|
|
||||||
namespace DX11
|
namespace DX11
|
||||||
{
|
{
|
||||||
|
|
||||||
using namespace D3D;
|
using namespace D3D;
|
||||||
|
|
||||||
ID3D11Buffer* indexbuffers[NUM_INDEXBUFFERS] = {};
|
ID3D11Buffer* indexbuffers[NUM_INDEXBUFFERS] = {};
|
||||||
ID3D11Buffer* vertexbuffers[NUM_VERTEXBUFFERS] = {};
|
ID3D11Buffer* vertexbuffers[NUM_VERTEXBUFFERS] = {};
|
||||||
|
|
||||||
// TODO: these seem ugly
|
// TODO: these seem ugly
|
||||||
inline ID3D11Buffer* GetSuitableIndexBuffer(const u32 minsize)
|
inline ID3D11Buffer* GetSuitableIndexBuffer(const u32 minsize)
|
||||||
{
|
{
|
||||||
for (u32 k = 0; k < NUM_INDEXBUFFERS - 1; ++k)
|
for (u32 k = 0; k < NUM_INDEXBUFFERS - 1; ++k)
|
||||||
if (minsize > (((u32)MAXIBUFFERSIZE) >> k))
|
if (minsize > (((u32)MAXIBUFFERSIZE) >> k))
|
||||||
return indexbuffers[k];
|
return indexbuffers[k];
|
||||||
return indexbuffers[NUM_INDEXBUFFERS - 1];
|
return indexbuffers[NUM_INDEXBUFFERS - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline ID3D11Buffer* GetSuitableVertexBuffer(const u32 minsize)
|
inline ID3D11Buffer* GetSuitableVertexBuffer(const u32 minsize)
|
||||||
{
|
{
|
||||||
for (u32 k = 0; k < NUM_VERTEXBUFFERS - 1; ++k)
|
for (u32 k = 0; k < NUM_VERTEXBUFFERS - 1; ++k)
|
||||||
if (minsize > (((u32)MAXVBUFFERSIZE) >> (k + 1)))
|
if (minsize > (((u32)MAXVBUFFERSIZE) >> (k + 1)))
|
||||||
return vertexbuffers[k];
|
return vertexbuffers[k];
|
||||||
return vertexbuffers[NUM_VERTEXBUFFERS - 1];
|
return vertexbuffers[NUM_VERTEXBUFFERS - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreateDeviceObjects()
|
void CreateDeviceObjects()
|
||||||
{
|
{
|
||||||
D3D11_BUFFER_DESC bufdesc = CD3D11_BUFFER_DESC(MAXIBUFFERSIZE * 2,
|
D3D11_BUFFER_DESC bufdesc = CD3D11_BUFFER_DESC(MAXIBUFFERSIZE * 2,
|
||||||
D3D11_BIND_INDEX_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
D3D11_BIND_INDEX_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
||||||
for (u32 k = 0; k < NUM_INDEXBUFFERS; ++k, bufdesc.ByteWidth >>= 1)
|
for (u32 k = 0; k < NUM_INDEXBUFFERS; ++k, bufdesc.ByteWidth >>= 1)
|
||||||
{
|
{
|
||||||
CHECK(SUCCEEDED(D3D::device->CreateBuffer(&bufdesc, NULL, indexbuffers + k)),
|
CHECK(SUCCEEDED(D3D::device->CreateBuffer(&bufdesc, NULL, indexbuffers + k)),
|
||||||
"Failed to create index buffer [%i].", k);
|
"Failed to create index buffer [%i].", k);
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)indexbuffers[k], "an index buffer of VertexManager");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)indexbuffers[k], "an index buffer of VertexManager");
|
||||||
}
|
}
|
||||||
|
|
||||||
bufdesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
bufdesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
||||||
bufdesc.ByteWidth = MAXVBUFFERSIZE;
|
bufdesc.ByteWidth = MAXVBUFFERSIZE;
|
||||||
for (u32 k = 0; k < NUM_VERTEXBUFFERS; ++k, bufdesc.ByteWidth >>= 1)
|
for (u32 k = 0; k < NUM_VERTEXBUFFERS; ++k, bufdesc.ByteWidth >>= 1)
|
||||||
{
|
{
|
||||||
CHECK(SUCCEEDED(D3D::device->CreateBuffer(&bufdesc, NULL, vertexbuffers + k)),
|
CHECK(SUCCEEDED(D3D::device->CreateBuffer(&bufdesc, NULL, vertexbuffers + k)),
|
||||||
"Failed to create vertex buffer [%i].", k);
|
"Failed to create vertex buffer [%i].", k);
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)vertexbuffers[k], "a vertex buffer of VertexManager");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)vertexbuffers[k], "a vertex buffer of VertexManager");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DestroyDeviceObjects()
|
void DestroyDeviceObjects()
|
||||||
{
|
{
|
||||||
for (u32 k = 0; k < NUM_INDEXBUFFERS; ++k)
|
for (u32 k = 0; k < NUM_INDEXBUFFERS; ++k)
|
||||||
SAFE_RELEASE(indexbuffers[k]);
|
SAFE_RELEASE(indexbuffers[k]);
|
||||||
|
|
||||||
for (u32 k = 0; k < NUM_VERTEXBUFFERS; ++k)
|
for (u32 k = 0; k < NUM_VERTEXBUFFERS; ++k)
|
||||||
SAFE_RELEASE(vertexbuffers[k]);
|
SAFE_RELEASE(vertexbuffers[k]);
|
||||||
}
|
}
|
||||||
|
|
||||||
VertexManager::VertexManager()
|
VertexManager::VertexManager()
|
||||||
{
|
{
|
||||||
CreateDeviceObjects();
|
CreateDeviceObjects();
|
||||||
}
|
}
|
||||||
|
|
||||||
VertexManager::~VertexManager()
|
VertexManager::~VertexManager()
|
||||||
{
|
{
|
||||||
DestroyDeviceObjects();
|
DestroyDeviceObjects();
|
||||||
ResetBuffer();
|
ResetBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexManager::Draw(u32 stride, bool alphapass)
|
void VertexManager::Draw(u32 stride, bool alphapass)
|
||||||
{
|
{
|
||||||
static const UINT bufoffset = 0;
|
static const UINT bufoffset = 0;
|
||||||
const UINT bufstride = stride;
|
const UINT bufstride = stride;
|
||||||
|
|
||||||
D3D11_MAPPED_SUBRESOURCE map;
|
D3D11_MAPPED_SUBRESOURCE map;
|
||||||
ID3D11Buffer* const vertexbuffer = GetSuitableVertexBuffer((u32)(s_pCurBufferPointer - LocalVBuffer));
|
ID3D11Buffer* const vertexbuffer = GetSuitableVertexBuffer((u32)(s_pCurBufferPointer - LocalVBuffer));
|
||||||
|
|
||||||
if (alphapass)
|
if (alphapass)
|
||||||
{
|
{
|
||||||
gfxstate->AlphaPass();
|
gfxstate->AlphaPass();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
context->Map(vertexbuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
context->Map(vertexbuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
||||||
memcpy(map.pData, LocalVBuffer, (u32)(s_pCurBufferPointer - LocalVBuffer));
|
memcpy(map.pData, LocalVBuffer, (u32)(s_pCurBufferPointer - LocalVBuffer));
|
||||||
context->Unmap(vertexbuffer, 0);
|
context->Unmap(vertexbuffer, 0);
|
||||||
|
|
||||||
gfxstate->ApplyState();
|
gfxstate->ApplyState();
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D::context->IASetVertexBuffers(0, 1, &vertexbuffer, &bufstride, &bufoffset);
|
D3D::context->IASetVertexBuffers(0, 1, &vertexbuffer, &bufstride, &bufoffset);
|
||||||
|
|
||||||
if (IndexGenerator::GetNumTriangles() > 0)
|
if (IndexGenerator::GetNumTriangles() > 0)
|
||||||
{
|
{
|
||||||
u32 indexbuffersize = IndexGenerator::GetTriangleindexLen();
|
u32 indexbuffersize = IndexGenerator::GetTriangleindexLen();
|
||||||
ID3D11Buffer* indexbuffer = GetSuitableIndexBuffer(2*indexbuffersize);
|
ID3D11Buffer* indexbuffer = GetSuitableIndexBuffer(2*indexbuffersize);
|
||||||
if (!alphapass)
|
if (!alphapass)
|
||||||
{
|
{
|
||||||
D3D::context->Map(indexbuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
D3D::context->Map(indexbuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
||||||
memcpy(map.pData, TIBuffer, 2*indexbuffersize);
|
memcpy(map.pData, TIBuffer, 2*indexbuffersize);
|
||||||
D3D::context->Unmap(indexbuffer, 0);
|
D3D::context->Unmap(indexbuffer, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||||
D3D::context->IASetIndexBuffer(indexbuffer, DXGI_FORMAT_R16_UINT, 0);
|
D3D::context->IASetIndexBuffer(indexbuffer, DXGI_FORMAT_R16_UINT, 0);
|
||||||
|
|
||||||
D3D::context->DrawIndexed(indexbuffersize, 0, 0);
|
D3D::context->DrawIndexed(indexbuffersize, 0, 0);
|
||||||
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
|
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
|
||||||
}
|
}
|
||||||
if (IndexGenerator::GetNumLines() > 0)
|
if (IndexGenerator::GetNumLines() > 0)
|
||||||
{
|
{
|
||||||
u32 indexbuffersize = IndexGenerator::GetLineindexLen();
|
u32 indexbuffersize = IndexGenerator::GetLineindexLen();
|
||||||
ID3D11Buffer* indexbuffer = GetSuitableIndexBuffer(2*indexbuffersize);
|
ID3D11Buffer* indexbuffer = GetSuitableIndexBuffer(2*indexbuffersize);
|
||||||
if (!alphapass)
|
if (!alphapass)
|
||||||
{
|
{
|
||||||
D3D::context->Map(indexbuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
D3D::context->Map(indexbuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
||||||
memcpy(map.pData, LIBuffer, 2*indexbuffersize);
|
memcpy(map.pData, LIBuffer, 2*indexbuffersize);
|
||||||
D3D::context->Unmap(indexbuffer, 0);
|
D3D::context->Unmap(indexbuffer, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST);
|
D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST);
|
||||||
D3D::context->IASetIndexBuffer(indexbuffer, DXGI_FORMAT_R16_UINT, 0);
|
D3D::context->IASetIndexBuffer(indexbuffer, DXGI_FORMAT_R16_UINT, 0);
|
||||||
|
|
||||||
D3D::context->DrawIndexed(indexbuffersize, 0, 0);
|
D3D::context->DrawIndexed(indexbuffersize, 0, 0);
|
||||||
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
|
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
|
||||||
}
|
}
|
||||||
if (IndexGenerator::GetNumPoints() > 0)
|
if (IndexGenerator::GetNumPoints() > 0)
|
||||||
{
|
{
|
||||||
u32 indexbuffersize = IndexGenerator::GetPointindexLen();
|
u32 indexbuffersize = IndexGenerator::GetPointindexLen();
|
||||||
ID3D11Buffer* indexbuffer = GetSuitableIndexBuffer(2*indexbuffersize);
|
ID3D11Buffer* indexbuffer = GetSuitableIndexBuffer(2*indexbuffersize);
|
||||||
if (!alphapass)
|
if (!alphapass)
|
||||||
{
|
{
|
||||||
D3D::context->Map(indexbuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
D3D::context->Map(indexbuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
||||||
memcpy(map.pData, PIBuffer, 2*indexbuffersize);
|
memcpy(map.pData, PIBuffer, 2*indexbuffersize);
|
||||||
D3D::context->Unmap(indexbuffer, 0);
|
D3D::context->Unmap(indexbuffer, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
|
D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
|
||||||
D3D::context->IASetIndexBuffer(indexbuffer, DXGI_FORMAT_R16_UINT, 0);
|
D3D::context->IASetIndexBuffer(indexbuffer, DXGI_FORMAT_R16_UINT, 0);
|
||||||
|
|
||||||
D3D::context->DrawIndexed(indexbuffersize, 0, 0);
|
D3D::context->DrawIndexed(indexbuffersize, 0, 0);
|
||||||
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
|
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,49 +1,49 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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/
|
||||||
|
|
||||||
#ifndef _DX11_VERTEXMANAGER_H
|
#ifndef _DX11_VERTEXMANAGER_H
|
||||||
#define _DX11_VERTEXMANAGER_H
|
#define _DX11_VERTEXMANAGER_H
|
||||||
|
|
||||||
#include "CPMemory.h"
|
#include "CPMemory.h"
|
||||||
#include "VertexLoader.h"
|
#include "VertexLoader.h"
|
||||||
|
|
||||||
#include "../VertexManager.h"
|
#include "../VertexManager.h"
|
||||||
|
|
||||||
namespace DX11
|
namespace DX11
|
||||||
{
|
{
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
// TODO: find sensible values for these two
|
// TODO: find sensible values for these two
|
||||||
NUM_VERTEXBUFFERS = 8,
|
NUM_VERTEXBUFFERS = 8,
|
||||||
NUM_INDEXBUFFERS = 10,
|
NUM_INDEXBUFFERS = 10,
|
||||||
};
|
};
|
||||||
|
|
||||||
class VertexManager : public ::VertexManagerBase
|
class VertexManager : public ::VertexManagerBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
VertexManager();
|
VertexManager();
|
||||||
~VertexManager();
|
~VertexManager();
|
||||||
|
|
||||||
void Draw(u32 stride, bool alphapass);
|
void Draw(u32 stride, bool alphapass);
|
||||||
|
|
||||||
NativeVertexFormat* CreateNativeVertexFormat();
|
NativeVertexFormat* CreateNativeVertexFormat();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,283 +1,283 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
// Common
|
// Common
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "FileUtil.h"
|
#include "FileUtil.h"
|
||||||
#include "LinearDiskCache.h"
|
#include "LinearDiskCache.h"
|
||||||
|
|
||||||
// VideoCommon
|
// VideoCommon
|
||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
#include "Statistics.h"
|
#include "Statistics.h"
|
||||||
#include "Profiler.h"
|
#include "Profiler.h"
|
||||||
#include "VertexLoader.h"
|
#include "VertexLoader.h"
|
||||||
#include "BPMemory.h"
|
#include "BPMemory.h"
|
||||||
#include "XFMemory.h"
|
#include "XFMemory.h"
|
||||||
|
|
||||||
// DX11
|
// DX11
|
||||||
#include "DX11_D3DBase.h"
|
#include "DX11_D3DBase.h"
|
||||||
#include "DX11_D3DShader.h"
|
#include "DX11_D3DShader.h"
|
||||||
#include "DX11_VertexShaderCache.h"
|
#include "DX11_VertexShaderCache.h"
|
||||||
#include "DX11_Render.h"
|
#include "DX11_Render.h"
|
||||||
|
|
||||||
#include "../Main.h"
|
#include "../Main.h"
|
||||||
|
|
||||||
namespace DX11
|
namespace DX11
|
||||||
{
|
{
|
||||||
|
|
||||||
VertexShaderCache::VSCache VertexShaderCache::vshaders;
|
VertexShaderCache::VSCache VertexShaderCache::vshaders;
|
||||||
const VertexShaderCache::VSCacheEntry* VertexShaderCache::last_entry;
|
const VertexShaderCache::VSCacheEntry* VertexShaderCache::last_entry;
|
||||||
|
|
||||||
static ID3D11VertexShader* SimpleVertexShader = NULL;
|
static ID3D11VertexShader* SimpleVertexShader = NULL;
|
||||||
static ID3D11VertexShader* ClearVertexShader = NULL;
|
static ID3D11VertexShader* ClearVertexShader = NULL;
|
||||||
static ID3D11InputLayout* SimpleLayout = NULL;
|
static ID3D11InputLayout* SimpleLayout = NULL;
|
||||||
static ID3D11InputLayout* ClearLayout = NULL;
|
static ID3D11InputLayout* ClearLayout = NULL;
|
||||||
|
|
||||||
LinearDiskCache g_vs_disk_cache;
|
LinearDiskCache g_vs_disk_cache;
|
||||||
|
|
||||||
ID3D11VertexShader* VertexShaderCache::GetSimpleVertexShader() { return SimpleVertexShader; }
|
ID3D11VertexShader* VertexShaderCache::GetSimpleVertexShader() { return SimpleVertexShader; }
|
||||||
ID3D11VertexShader* VertexShaderCache::GetClearVertexShader() { return ClearVertexShader; }
|
ID3D11VertexShader* VertexShaderCache::GetClearVertexShader() { return ClearVertexShader; }
|
||||||
ID3D11InputLayout* VertexShaderCache::GetSimpleInputLayout() { return SimpleLayout; }
|
ID3D11InputLayout* VertexShaderCache::GetSimpleInputLayout() { return SimpleLayout; }
|
||||||
ID3D11InputLayout* VertexShaderCache::GetClearInputLayout() { return ClearLayout; }
|
ID3D11InputLayout* VertexShaderCache::GetClearInputLayout() { return ClearLayout; }
|
||||||
|
|
||||||
// maps the constant numbers to float indices in the constant buffer
|
// maps the constant numbers to float indices in the constant buffer
|
||||||
unsigned int vs_constant_offset_table[C_VENVCONST_END];
|
unsigned int vs_constant_offset_table[C_VENVCONST_END];
|
||||||
void VertexShaderCache::SetVSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4)
|
void VertexShaderCache::SetVSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4)
|
||||||
{
|
{
|
||||||
D3D::gfxstate->vsconstants[vs_constant_offset_table[const_number] ] = f1;
|
D3D::gfxstate->vsconstants[vs_constant_offset_table[const_number] ] = f1;
|
||||||
D3D::gfxstate->vsconstants[vs_constant_offset_table[const_number]+1] = f2;
|
D3D::gfxstate->vsconstants[vs_constant_offset_table[const_number]+1] = f2;
|
||||||
D3D::gfxstate->vsconstants[vs_constant_offset_table[const_number]+2] = f3;
|
D3D::gfxstate->vsconstants[vs_constant_offset_table[const_number]+2] = f3;
|
||||||
D3D::gfxstate->vsconstants[vs_constant_offset_table[const_number]+3] = f4;
|
D3D::gfxstate->vsconstants[vs_constant_offset_table[const_number]+3] = f4;
|
||||||
D3D::gfxstate->vscbufchanged = true;
|
D3D::gfxstate->vscbufchanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexShaderCache::SetVSConstant4fv(unsigned int const_number, const float* f)
|
void VertexShaderCache::SetVSConstant4fv(unsigned int const_number, const float* f)
|
||||||
{
|
{
|
||||||
memcpy(&D3D::gfxstate->vsconstants[vs_constant_offset_table[const_number]], f, sizeof(float)*4);
|
memcpy(&D3D::gfxstate->vsconstants[vs_constant_offset_table[const_number]], f, sizeof(float)*4);
|
||||||
D3D::gfxstate->vscbufchanged = true;
|
D3D::gfxstate->vscbufchanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexShaderCache::SetMultiVSConstant3fv(unsigned int const_number, unsigned int count, const float* f)
|
void VertexShaderCache::SetMultiVSConstant3fv(unsigned int const_number, unsigned int count, const float* f)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
memcpy(&D3D::gfxstate->vsconstants[vs_constant_offset_table[const_number+i]], f+3*i, sizeof(float)*3);
|
memcpy(&D3D::gfxstate->vsconstants[vs_constant_offset_table[const_number+i]], f+3*i, sizeof(float)*3);
|
||||||
D3D::gfxstate->vsconstants[vs_constant_offset_table[const_number+i]+3] = 0.f;
|
D3D::gfxstate->vsconstants[vs_constant_offset_table[const_number+i]+3] = 0.f;
|
||||||
}
|
}
|
||||||
D3D::gfxstate->vscbufchanged = true;
|
D3D::gfxstate->vscbufchanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexShaderCache::SetMultiVSConstant4fv(unsigned int const_number, unsigned int count, const float* f)
|
void VertexShaderCache::SetMultiVSConstant4fv(unsigned int const_number, unsigned int count, const float* f)
|
||||||
{
|
{
|
||||||
memcpy(&D3D::gfxstate->vsconstants[vs_constant_offset_table[const_number]], f, sizeof(float)*4*count);
|
memcpy(&D3D::gfxstate->vsconstants[vs_constant_offset_table[const_number]], f, sizeof(float)*4*count);
|
||||||
D3D::gfxstate->vscbufchanged = true;
|
D3D::gfxstate->vscbufchanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// this class will load the precompiled shaders into our cache
|
// this class will load the precompiled shaders into our cache
|
||||||
class VertexShaderCacheInserter : public LinearDiskCacheReader {
|
class VertexShaderCacheInserter : public LinearDiskCacheReader {
|
||||||
public:
|
public:
|
||||||
void Read(const u8* key, int key_size, const u8* value, int value_size)
|
void Read(const u8* key, int key_size, const u8* value, int value_size)
|
||||||
{
|
{
|
||||||
VERTEXSHADERUID uid;
|
VERTEXSHADERUID uid;
|
||||||
if (key_size != sizeof(uid))
|
if (key_size != sizeof(uid))
|
||||||
{
|
{
|
||||||
ERROR_LOG(VIDEO, "Wrong key size in vertex shader cache");
|
ERROR_LOG(VIDEO, "Wrong key size in vertex shader cache");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memcpy(&uid, key, key_size);
|
memcpy(&uid, key, key_size);
|
||||||
|
|
||||||
D3DBlob* blob = new D3DBlob(value_size, value);
|
D3DBlob* blob = new D3DBlob(value_size, value);
|
||||||
VertexShaderCache::InsertByteCode(uid, blob);
|
VertexShaderCache::InsertByteCode(uid, blob);
|
||||||
blob->Release();
|
blob->Release();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const char simple_shader_code[] = {
|
const char simple_shader_code[] = {
|
||||||
"struct VSOUTPUT\n"
|
"struct VSOUTPUT\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
"float4 vPosition : POSITION;\n"
|
"float4 vPosition : POSITION;\n"
|
||||||
"float2 vTexCoord : TEXCOORD0;\n"
|
"float2 vTexCoord : TEXCOORD0;\n"
|
||||||
"};\n"
|
"};\n"
|
||||||
"VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0)\n"
|
"VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
"VSOUTPUT OUT;\n"
|
"VSOUTPUT OUT;\n"
|
||||||
"OUT.vPosition = inPosition;\n"
|
"OUT.vPosition = inPosition;\n"
|
||||||
"OUT.vTexCoord = inTEX0;\n"
|
"OUT.vTexCoord = inTEX0;\n"
|
||||||
"return OUT;\n"
|
"return OUT;\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
};
|
};
|
||||||
|
|
||||||
const char clear_shader_code[] = {
|
const char clear_shader_code[] = {
|
||||||
"struct VSOUTPUT\n"
|
"struct VSOUTPUT\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
"float4 vPosition : POSITION;\n"
|
"float4 vPosition : POSITION;\n"
|
||||||
"float4 vColor0 : COLOR0;\n"
|
"float4 vColor0 : COLOR0;\n"
|
||||||
"};\n"
|
"};\n"
|
||||||
"VSOUTPUT main(float4 inPosition : POSITION,float4 inColor0: COLOR0)\n"
|
"VSOUTPUT main(float4 inPosition : POSITION,float4 inColor0: COLOR0)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
"VSOUTPUT OUT;\n"
|
"VSOUTPUT OUT;\n"
|
||||||
"OUT.vPosition = inPosition;\n"
|
"OUT.vPosition = inPosition;\n"
|
||||||
"OUT.vColor0 = inColor0;\n"
|
"OUT.vColor0 = inColor0;\n"
|
||||||
"return OUT;\n"
|
"return OUT;\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
};
|
};
|
||||||
|
|
||||||
VertexShaderCache::VertexShaderCache()
|
VertexShaderCache::VertexShaderCache()
|
||||||
{
|
{
|
||||||
const D3D11_INPUT_ELEMENT_DESC simpleelems[2] =
|
const D3D11_INPUT_ELEMENT_DESC simpleelems[2] =
|
||||||
{
|
{
|
||||||
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||||
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||||
};
|
};
|
||||||
const D3D11_INPUT_ELEMENT_DESC clearelems[2] =
|
const D3D11_INPUT_ELEMENT_DESC clearelems[2] =
|
||||||
{
|
{
|
||||||
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||||
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
D3DBlob* blob;
|
D3DBlob* blob;
|
||||||
D3D::CompileVertexShader(simple_shader_code, sizeof(simple_shader_code), &blob);
|
D3D::CompileVertexShader(simple_shader_code, sizeof(simple_shader_code), &blob);
|
||||||
D3D::device->CreateInputLayout(simpleelems, 2, blob->Data(), blob->Size(), &SimpleLayout);
|
D3D::device->CreateInputLayout(simpleelems, 2, blob->Data(), blob->Size(), &SimpleLayout);
|
||||||
SimpleVertexShader = D3D::CreateVertexShaderFromByteCode(blob);
|
SimpleVertexShader = D3D::CreateVertexShaderFromByteCode(blob);
|
||||||
if (SimpleLayout == NULL || SimpleVertexShader == NULL) PanicAlert("Failed to create simple vertex shader or input layout at %s %d\n", __FILE__, __LINE__);
|
if (SimpleLayout == NULL || SimpleVertexShader == NULL) PanicAlert("Failed to create simple vertex shader or input layout at %s %d\n", __FILE__, __LINE__);
|
||||||
blob->Release();
|
blob->Release();
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)SimpleVertexShader, "simple vertex shader");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)SimpleVertexShader, "simple vertex shader");
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)SimpleLayout, "simple input layout");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)SimpleLayout, "simple input layout");
|
||||||
|
|
||||||
D3D::CompileVertexShader(clear_shader_code, sizeof(clear_shader_code), &blob);
|
D3D::CompileVertexShader(clear_shader_code, sizeof(clear_shader_code), &blob);
|
||||||
D3D::device->CreateInputLayout(clearelems, 2, blob->Data(), blob->Size(), &ClearLayout);
|
D3D::device->CreateInputLayout(clearelems, 2, blob->Data(), blob->Size(), &ClearLayout);
|
||||||
ClearVertexShader = D3D::CreateVertexShaderFromByteCode(blob);
|
ClearVertexShader = D3D::CreateVertexShaderFromByteCode(blob);
|
||||||
if (ClearLayout == NULL || ClearVertexShader == NULL) PanicAlert("Failed to create clear vertex shader or input layout at %s %d\n", __FILE__, __LINE__);
|
if (ClearLayout == NULL || ClearVertexShader == NULL) PanicAlert("Failed to create clear vertex shader or input layout at %s %d\n", __FILE__, __LINE__);
|
||||||
blob->Release();
|
blob->Release();
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)ClearVertexShader, "clear vertex shader");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)ClearVertexShader, "clear vertex shader");
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)ClearLayout, "clear input layout");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)ClearLayout, "clear input layout");
|
||||||
|
|
||||||
Clear();
|
Clear();
|
||||||
|
|
||||||
// these values are hardcoded, they depend on internal D3DCompile behavior
|
// these values are hardcoded, they depend on internal D3DCompile behavior
|
||||||
// TODO: Do this with D3DReflect or something instead
|
// TODO: Do this with D3DReflect or something instead
|
||||||
unsigned int k;
|
unsigned int k;
|
||||||
for (k = 0;k < 6;k++) vs_constant_offset_table[C_POSNORMALMATRIX+k] = 0+4*k;
|
for (k = 0;k < 6;k++) vs_constant_offset_table[C_POSNORMALMATRIX+k] = 0+4*k;
|
||||||
for (k = 0;k < 4;k++) vs_constant_offset_table[C_PROJECTION+k] = 24+4*k;
|
for (k = 0;k < 4;k++) vs_constant_offset_table[C_PROJECTION+k] = 24+4*k;
|
||||||
for (k = 0;k < 4;k++) vs_constant_offset_table[C_MATERIALS+k] = 40+4*k;
|
for (k = 0;k < 4;k++) vs_constant_offset_table[C_MATERIALS+k] = 40+4*k;
|
||||||
for (k = 0;k < 40;k++) vs_constant_offset_table[C_LIGHTS+k] = 56+4*k;
|
for (k = 0;k < 40;k++) vs_constant_offset_table[C_LIGHTS+k] = 56+4*k;
|
||||||
for (k = 0;k < 24;k++) vs_constant_offset_table[C_TEXMATRICES+k] = 216+4*k;
|
for (k = 0;k < 24;k++) vs_constant_offset_table[C_TEXMATRICES+k] = 216+4*k;
|
||||||
for (k = 0;k < 64;k++) vs_constant_offset_table[C_TRANSFORMMATRICES+k] = 312+4*k;
|
for (k = 0;k < 64;k++) vs_constant_offset_table[C_TRANSFORMMATRICES+k] = 312+4*k;
|
||||||
for (k = 0;k < 32;k++) vs_constant_offset_table[C_NORMALMATRICES+k] = 568+4*k;
|
for (k = 0;k < 32;k++) vs_constant_offset_table[C_NORMALMATRICES+k] = 568+4*k;
|
||||||
for (k = 0;k < 64;k++) vs_constant_offset_table[C_POSTTRANSFORMMATRICES+k] = 696+4*k;
|
for (k = 0;k < 64;k++) vs_constant_offset_table[C_POSTTRANSFORMMATRICES+k] = 696+4*k;
|
||||||
for (k = 0;k < 4;k++) vs_constant_offset_table[C_DEPTHPARAMS+k] = 952+4*k;
|
for (k = 0;k < 4;k++) vs_constant_offset_table[C_DEPTHPARAMS+k] = 952+4*k;
|
||||||
|
|
||||||
if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX)))
|
if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX)))
|
||||||
File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX));
|
File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX));
|
||||||
|
|
||||||
char cache_filename[MAX_PATH];
|
char cache_filename[MAX_PATH];
|
||||||
sprintf(cache_filename, "%sdx11-%s-vs.cache", File::GetUserPath(D_SHADERCACHE_IDX), g_globals->unique_id);
|
sprintf(cache_filename, "%sdx11-%s-vs.cache", File::GetUserPath(D_SHADERCACHE_IDX), g_globals->unique_id);
|
||||||
VertexShaderCacheInserter inserter;
|
VertexShaderCacheInserter inserter;
|
||||||
g_vs_disk_cache.OpenAndRead(cache_filename, &inserter);
|
g_vs_disk_cache.OpenAndRead(cache_filename, &inserter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexShaderCache::Clear()
|
void VertexShaderCache::Clear()
|
||||||
{
|
{
|
||||||
for (VSCache::iterator iter = vshaders.begin(); iter != vshaders.end(); ++iter)
|
for (VSCache::iterator iter = vshaders.begin(); iter != vshaders.end(); ++iter)
|
||||||
iter->second.Destroy();
|
iter->second.Destroy();
|
||||||
vshaders.clear();
|
vshaders.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
VertexShaderCache::~VertexShaderCache()
|
VertexShaderCache::~VertexShaderCache()
|
||||||
{
|
{
|
||||||
SAFE_RELEASE(SimpleVertexShader);
|
SAFE_RELEASE(SimpleVertexShader);
|
||||||
SAFE_RELEASE(ClearVertexShader);
|
SAFE_RELEASE(ClearVertexShader);
|
||||||
|
|
||||||
SAFE_RELEASE(SimpleLayout);
|
SAFE_RELEASE(SimpleLayout);
|
||||||
SAFE_RELEASE(ClearLayout);
|
SAFE_RELEASE(ClearLayout);
|
||||||
|
|
||||||
Clear();
|
Clear();
|
||||||
g_vs_disk_cache.Sync();
|
g_vs_disk_cache.Sync();
|
||||||
g_vs_disk_cache.Close();
|
g_vs_disk_cache.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VertexShaderCache::SetShader(u32 components)
|
bool VertexShaderCache::SetShader(u32 components)
|
||||||
{
|
{
|
||||||
DVSTARTPROFILE();
|
DVSTARTPROFILE();
|
||||||
|
|
||||||
VERTEXSHADERUID uid;
|
VERTEXSHADERUID uid;
|
||||||
GetVertexShaderId(&uid, components);
|
GetVertexShaderId(&uid, components);
|
||||||
if (uid == last_vertex_shader_uid && vshaders[uid].frameCount == frameCount)
|
if (uid == last_vertex_shader_uid && vshaders[uid].frameCount == frameCount)
|
||||||
return (vshaders[uid].shader != NULL);
|
return (vshaders[uid].shader != NULL);
|
||||||
|
|
||||||
memcpy(&last_vertex_shader_uid, &uid, sizeof(VERTEXSHADERUID));
|
memcpy(&last_vertex_shader_uid, &uid, sizeof(VERTEXSHADERUID));
|
||||||
|
|
||||||
VSCache::iterator iter;
|
VSCache::iterator iter;
|
||||||
iter = vshaders.find(uid);
|
iter = vshaders.find(uid);
|
||||||
if (iter != vshaders.end())
|
if (iter != vshaders.end())
|
||||||
{
|
{
|
||||||
iter->second.frameCount = frameCount;
|
iter->second.frameCount = frameCount;
|
||||||
const VSCacheEntry &entry = iter->second;
|
const VSCacheEntry &entry = iter->second;
|
||||||
last_entry = &entry;
|
last_entry = &entry;
|
||||||
|
|
||||||
if (entry.shader) D3D::gfxstate->SetVShader(entry.shader, iter->second.bytecode);
|
if (entry.shader) D3D::gfxstate->SetVShader(entry.shader, iter->second.bytecode);
|
||||||
return (entry.shader != NULL);
|
return (entry.shader != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* code = GenerateVertexShaderCode(components, API_D3D11);
|
const char* code = GenerateVertexShaderCode(components, API_D3D11);
|
||||||
|
|
||||||
D3DBlob* pbytecode = NULL;
|
D3DBlob* pbytecode = NULL;
|
||||||
D3D::CompileVertexShader(code, (int)strlen(code), &pbytecode);
|
D3D::CompileVertexShader(code, (int)strlen(code), &pbytecode);
|
||||||
|
|
||||||
if (pbytecode == NULL)
|
if (pbytecode == NULL)
|
||||||
{
|
{
|
||||||
PanicAlert("Failed to compile Vertex Shader %s %d:\n\n%s", __FILE__, __LINE__, code);
|
PanicAlert("Failed to compile Vertex Shader %s %d:\n\n%s", __FILE__, __LINE__, code);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
g_vs_disk_cache.Append((u8*)&uid, sizeof(uid), (const u8*)pbytecode->Data(), pbytecode->Size());
|
g_vs_disk_cache.Append((u8*)&uid, sizeof(uid), (const u8*)pbytecode->Data(), pbytecode->Size());
|
||||||
g_vs_disk_cache.Sync();
|
g_vs_disk_cache.Sync();
|
||||||
|
|
||||||
bool result = InsertByteCode(uid, pbytecode);
|
bool result = InsertByteCode(uid, pbytecode);
|
||||||
D3D::gfxstate->SetVShader(last_entry->shader, last_entry->bytecode);
|
D3D::gfxstate->SetVShader(last_entry->shader, last_entry->bytecode);
|
||||||
pbytecode->Release();
|
pbytecode->Release();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VertexShaderCache::InsertByteCode(const VERTEXSHADERUID &uid, D3DBlob* bcodeblob)
|
bool VertexShaderCache::InsertByteCode(const VERTEXSHADERUID &uid, D3DBlob* bcodeblob)
|
||||||
{
|
{
|
||||||
ID3D11VertexShader* shader = D3D::CreateVertexShaderFromByteCode(bcodeblob);
|
ID3D11VertexShader* shader = D3D::CreateVertexShaderFromByteCode(bcodeblob);
|
||||||
if (shader == NULL)
|
if (shader == NULL)
|
||||||
{
|
{
|
||||||
PanicAlert("Failed to create vertex shader from %p size %d at %s %d\n", bcodeblob->Data(), bcodeblob->Size(), __FILE__, __LINE__);
|
PanicAlert("Failed to create vertex shader from %p size %d at %s %d\n", bcodeblob->Data(), bcodeblob->Size(), __FILE__, __LINE__);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// TODO: Somehow make the debug name a bit more specific
|
// TODO: Somehow make the debug name a bit more specific
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)shader, "a vertex shader of VertexShaderCache");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)shader, "a vertex shader of VertexShaderCache");
|
||||||
|
|
||||||
// Make an entry in the table
|
// Make an entry in the table
|
||||||
VSCacheEntry entry;
|
VSCacheEntry entry;
|
||||||
entry.shader = shader;
|
entry.shader = shader;
|
||||||
entry.frameCount = frameCount;
|
entry.frameCount = frameCount;
|
||||||
entry.SetByteCode(bcodeblob);
|
entry.SetByteCode(bcodeblob);
|
||||||
|
|
||||||
vshaders[uid] = entry;
|
vshaders[uid] = entry;
|
||||||
last_entry = &vshaders[uid];
|
last_entry = &vshaders[uid];
|
||||||
|
|
||||||
INCSTAT(stats.numVertexShadersCreated);
|
INCSTAT(stats.numVertexShadersCreated);
|
||||||
SETSTAT(stats.numVertexShadersAlive, (int)vshaders.size());
|
SETSTAT(stats.numVertexShadersAlive, (int)vshaders.size());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,80 +1,80 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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/
|
||||||
|
|
||||||
#ifndef _DX11_VERTEXSHADERCACHE_H
|
#ifndef _DX11_VERTEXSHADERCACHE_H
|
||||||
#define _DX11_VERTEXSHADERCACHE_H
|
#define _DX11_VERTEXSHADERCACHE_H
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include "VertexShaderGen.h"
|
#include "VertexShaderGen.h"
|
||||||
#include "DX11_D3DBase.h"
|
#include "DX11_D3DBase.h"
|
||||||
|
|
||||||
#include "../VertexShaderCache.h"
|
#include "../VertexShaderCache.h"
|
||||||
|
|
||||||
namespace DX11
|
namespace DX11
|
||||||
{
|
{
|
||||||
|
|
||||||
class VertexShaderCache : public ::VertexShaderCacheBase
|
class VertexShaderCache : public ::VertexShaderCacheBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
VertexShaderCache();
|
VertexShaderCache();
|
||||||
~VertexShaderCache();
|
~VertexShaderCache();
|
||||||
|
|
||||||
static void Clear();
|
static void Clear();
|
||||||
bool SetShader(u32 components);
|
bool SetShader(u32 components);
|
||||||
|
|
||||||
static ID3D11VertexShader* GetSimpleVertexShader();
|
static ID3D11VertexShader* GetSimpleVertexShader();
|
||||||
static ID3D11VertexShader* GetClearVertexShader();
|
static ID3D11VertexShader* GetClearVertexShader();
|
||||||
static ID3D11InputLayout* GetSimpleInputLayout();
|
static ID3D11InputLayout* GetSimpleInputLayout();
|
||||||
static ID3D11InputLayout* GetClearInputLayout();
|
static ID3D11InputLayout* GetClearInputLayout();
|
||||||
|
|
||||||
static bool VertexShaderCache::InsertByteCode(const VERTEXSHADERUID &uid, D3DBlob* bcodeblob);
|
static bool VertexShaderCache::InsertByteCode(const VERTEXSHADERUID &uid, D3DBlob* bcodeblob);
|
||||||
|
|
||||||
void SetVSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4);
|
void SetVSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4);
|
||||||
void SetVSConstant4fv(unsigned int const_number, const float* f);
|
void SetVSConstant4fv(unsigned int const_number, const float* f);
|
||||||
void SetMultiVSConstant3fv(unsigned int const_number, unsigned int count, const float* f);
|
void SetMultiVSConstant3fv(unsigned int const_number, unsigned int count, const float* f);
|
||||||
void SetMultiVSConstant4fv(unsigned int const_number, unsigned int count, const float* f);
|
void SetMultiVSConstant4fv(unsigned int const_number, unsigned int count, const float* f);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct VSCacheEntry
|
struct VSCacheEntry
|
||||||
{
|
{
|
||||||
ID3D11VertexShader* shader;
|
ID3D11VertexShader* shader;
|
||||||
D3DBlob* bytecode; // needed to initialize the input layout
|
D3DBlob* bytecode; // needed to initialize the input layout
|
||||||
int frameCount;
|
int frameCount;
|
||||||
|
|
||||||
VSCacheEntry() : shader(NULL), bytecode(NULL), frameCount(0) {}
|
VSCacheEntry() : shader(NULL), bytecode(NULL), frameCount(0) {}
|
||||||
void SetByteCode(D3DBlob* blob)
|
void SetByteCode(D3DBlob* blob)
|
||||||
{
|
{
|
||||||
SAFE_RELEASE(bytecode);
|
SAFE_RELEASE(bytecode);
|
||||||
bytecode = blob;
|
bytecode = blob;
|
||||||
blob->AddRef();
|
blob->AddRef();
|
||||||
}
|
}
|
||||||
void Destroy()
|
void Destroy()
|
||||||
{
|
{
|
||||||
SAFE_RELEASE(shader);
|
SAFE_RELEASE(shader);
|
||||||
SAFE_RELEASE(bytecode);
|
SAFE_RELEASE(bytecode);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
typedef std::map<VERTEXSHADERUID, VSCacheEntry> VSCache;
|
typedef std::map<VERTEXSHADERUID, VSCacheEntry> VSCache;
|
||||||
|
|
||||||
static VSCache vshaders;
|
static VSCache vshaders;
|
||||||
static const VSCacheEntry* last_entry;
|
static const VSCacheEntry* last_entry;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // _VERTEXSHADERCACHE_H
|
#endif // _VERTEXSHADERCACHE_H
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,165 +1,165 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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/
|
||||||
|
|
||||||
#ifndef _D3DBASE_H
|
#ifndef _D3DBASE_H
|
||||||
#define _D3DBASE_H
|
#define _D3DBASE_H
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
#include <d3dx9.h>
|
#include <d3dx9.h>
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
|
||||||
namespace DX9
|
namespace DX9
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace D3D
|
namespace D3D
|
||||||
{
|
{
|
||||||
|
|
||||||
#define SAFE_RELEASE(x) { if (x) (x)->Release(); (x) = NULL; }
|
#define SAFE_RELEASE(x) { if (x) (x)->Release(); (x) = NULL; }
|
||||||
#define SAFE_DELETE(x) { delete (x); (x) = NULL; }
|
#define SAFE_DELETE(x) { delete (x); (x) = NULL; }
|
||||||
|
|
||||||
// From http://developer.amd.com/gpu_assets/Advanced%20DX9%20Capabilities%20for%20ATI%20Radeon%20Cards.pdf
|
// From http://developer.amd.com/gpu_assets/Advanced%20DX9%20Capabilities%20for%20ATI%20Radeon%20Cards.pdf
|
||||||
// Magic FourCC's to unlock undocumented D3D9 features:
|
// Magic FourCC's to unlock undocumented D3D9 features:
|
||||||
|
|
||||||
// Z texture formats
|
// Z texture formats
|
||||||
#define FOURCC_INTZ ((D3DFORMAT)(MAKEFOURCC('I','N','T','Z')))
|
#define FOURCC_INTZ ((D3DFORMAT)(MAKEFOURCC('I','N','T','Z')))
|
||||||
#define FOURCC_RAWZ ((D3DFORMAT)(MAKEFOURCC('R','A','W','Z')))
|
#define FOURCC_RAWZ ((D3DFORMAT)(MAKEFOURCC('R','A','W','Z')))
|
||||||
#define FOURCC_DF24 ((D3DFORMAT)(MAKEFOURCC('D','F','2','4')))
|
#define FOURCC_DF24 ((D3DFORMAT)(MAKEFOURCC('D','F','2','4')))
|
||||||
#define FOURCC_DF16 ((D3DFORMAT)(MAKEFOURCC('D','F','1','6')))
|
#define FOURCC_DF16 ((D3DFORMAT)(MAKEFOURCC('D','F','1','6')))
|
||||||
|
|
||||||
// Depth buffer resolve:
|
// Depth buffer resolve:
|
||||||
#define FOURCC_RESZ ((D3DFORMAT)(MAKEFOURCC('R','E','S','Z')))
|
#define FOURCC_RESZ ((D3DFORMAT)(MAKEFOURCC('R','E','S','Z')))
|
||||||
#define RESZ_CODE 0x7fa05000
|
#define RESZ_CODE 0x7fa05000
|
||||||
|
|
||||||
// Null render target to do Z-only shadow maps: (probably not useful for Dolphin)
|
// Null render target to do Z-only shadow maps: (probably not useful for Dolphin)
|
||||||
#define FOURCC_NULL ((D3DFORMAT)(MAKEFOURCC('N','U','L','L')))
|
#define FOURCC_NULL ((D3DFORMAT)(MAKEFOURCC('N','U','L','L')))
|
||||||
|
|
||||||
bool IsATIDevice();
|
bool IsATIDevice();
|
||||||
HRESULT Init();
|
HRESULT Init();
|
||||||
HRESULT Create(int adapter, HWND wnd, int resolution, int aa_mode, bool auto_depth);
|
HRESULT Create(int adapter, HWND wnd, int resolution, int aa_mode, bool auto_depth);
|
||||||
void Close();
|
void Close();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
|
||||||
// Direct access to the device.
|
// Direct access to the device.
|
||||||
extern LPDIRECT3DDEVICE9 dev;
|
extern LPDIRECT3DDEVICE9 dev;
|
||||||
extern bool bFrameInProgress;
|
extern bool bFrameInProgress;
|
||||||
|
|
||||||
void Reset();
|
void Reset();
|
||||||
bool BeginFrame();
|
bool BeginFrame();
|
||||||
void EndFrame();
|
void EndFrame();
|
||||||
void Present();
|
void Present();
|
||||||
bool CanUseINTZ();
|
bool CanUseINTZ();
|
||||||
|
|
||||||
int GetBackBufferWidth();
|
int GetBackBufferWidth();
|
||||||
int GetBackBufferHeight();
|
int GetBackBufferHeight();
|
||||||
LPDIRECT3DSURFACE9 GetBackBufferSurface();
|
LPDIRECT3DSURFACE9 GetBackBufferSurface();
|
||||||
LPDIRECT3DSURFACE9 GetBackBufferDepthSurface();
|
LPDIRECT3DSURFACE9 GetBackBufferDepthSurface();
|
||||||
LPDIRECT3DVERTEXBUFFER9 GetquadVB();
|
LPDIRECT3DVERTEXBUFFER9 GetquadVB();
|
||||||
LPDIRECT3DVERTEXDECLARATION9 GetBasicvertexDecl();
|
LPDIRECT3DVERTEXDECLARATION9 GetBasicvertexDecl();
|
||||||
const D3DCAPS9 &GetCaps();
|
const D3DCAPS9 &GetCaps();
|
||||||
const char *PixelShaderVersionString();
|
const char *PixelShaderVersionString();
|
||||||
const char *VertexShaderVersionString();
|
const char *VertexShaderVersionString();
|
||||||
void ShowD3DError(HRESULT err);
|
void ShowD3DError(HRESULT err);
|
||||||
|
|
||||||
// The following are "filtered" versions of the corresponding D3Ddev-> functions.
|
// The following are "filtered" versions of the corresponding D3Ddev-> functions.
|
||||||
void SetTexture(DWORD Stage, IDirect3DBaseTexture9 *pTexture);
|
void SetTexture(DWORD Stage, IDirect3DBaseTexture9 *pTexture);
|
||||||
void SetRenderState(D3DRENDERSTATETYPE State, DWORD Value);
|
void SetRenderState(D3DRENDERSTATETYPE State, DWORD Value);
|
||||||
void RefreshRenderState(D3DRENDERSTATETYPE State);
|
void RefreshRenderState(D3DRENDERSTATETYPE State);
|
||||||
void ChangeRenderState(D3DRENDERSTATETYPE State, DWORD Value);
|
void ChangeRenderState(D3DRENDERSTATETYPE State, DWORD Value);
|
||||||
|
|
||||||
void SetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value);
|
void SetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value);
|
||||||
void RefreshTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type);
|
void RefreshTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type);
|
||||||
void ChangeTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value);
|
void ChangeTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value);
|
||||||
|
|
||||||
void SetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value);
|
void SetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value);
|
||||||
void RefreshSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type);
|
void RefreshSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type);
|
||||||
void ChangeSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value);
|
void ChangeSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value);
|
||||||
|
|
||||||
void RefreshVertexDeclaration();
|
void RefreshVertexDeclaration();
|
||||||
void SetVertexDeclaration(LPDIRECT3DVERTEXDECLARATION9 decl);
|
void SetVertexDeclaration(LPDIRECT3DVERTEXDECLARATION9 decl);
|
||||||
|
|
||||||
void RefreshVertexShader();
|
void RefreshVertexShader();
|
||||||
void SetVertexShader(LPDIRECT3DVERTEXSHADER9 shader);
|
void SetVertexShader(LPDIRECT3DVERTEXSHADER9 shader);
|
||||||
|
|
||||||
void RefreshPixelShader();
|
void RefreshPixelShader();
|
||||||
void SetPixelShader(LPDIRECT3DPIXELSHADER9 shader);
|
void SetPixelShader(LPDIRECT3DPIXELSHADER9 shader);
|
||||||
|
|
||||||
void ApplyCachedState();
|
void ApplyCachedState();
|
||||||
|
|
||||||
// Utility functions for vendor specific hacks. So far, just the one.
|
// Utility functions for vendor specific hacks. So far, just the one.
|
||||||
void EnableAlphaToCoverage();
|
void EnableAlphaToCoverage();
|
||||||
|
|
||||||
struct Resolution
|
struct Resolution
|
||||||
{
|
{
|
||||||
char name[32];
|
char name[32];
|
||||||
int xres;
|
int xres;
|
||||||
int yres;
|
int yres;
|
||||||
std::set<D3DFORMAT> bitdepths;
|
std::set<D3DFORMAT> bitdepths;
|
||||||
std::set<int> refreshes;
|
std::set<int> refreshes;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AALevel
|
struct AALevel
|
||||||
{
|
{
|
||||||
AALevel(const char *n, D3DMULTISAMPLE_TYPE m, int q) {
|
AALevel(const char *n, D3DMULTISAMPLE_TYPE m, int q) {
|
||||||
strncpy(name, n, 32);
|
strncpy(name, n, 32);
|
||||||
name[31] = '\0';
|
name[31] = '\0';
|
||||||
ms_setting = m;
|
ms_setting = m;
|
||||||
qual_setting = q;
|
qual_setting = q;
|
||||||
}
|
}
|
||||||
char name[32];
|
char name[32];
|
||||||
D3DMULTISAMPLE_TYPE ms_setting;
|
D3DMULTISAMPLE_TYPE ms_setting;
|
||||||
int qual_setting;
|
int qual_setting;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Adapter
|
struct Adapter
|
||||||
{
|
{
|
||||||
D3DADAPTER_IDENTIFIER9 ident;
|
D3DADAPTER_IDENTIFIER9 ident;
|
||||||
std::vector<Resolution> resolutions;
|
std::vector<Resolution> resolutions;
|
||||||
std::vector<AALevel> aa_levels;
|
std::vector<AALevel> aa_levels;
|
||||||
bool supports_alpha_to_coverage;
|
bool supports_alpha_to_coverage;
|
||||||
|
|
||||||
// Magic render targets, see the top of this file.
|
// Magic render targets, see the top of this file.
|
||||||
bool supports_intz;
|
bool supports_intz;
|
||||||
bool supports_rawz;
|
bool supports_rawz;
|
||||||
bool supports_resz;
|
bool supports_resz;
|
||||||
bool supports_null;
|
bool supports_null;
|
||||||
};
|
};
|
||||||
|
|
||||||
const Adapter &GetAdapter(int i);
|
const Adapter &GetAdapter(int i);
|
||||||
const Adapter &GetCurAdapter();
|
const Adapter &GetCurAdapter();
|
||||||
int GetNumAdapters();
|
int GetNumAdapters();
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
// Used to not require the SDK and runtime versions to match:
|
// Used to not require the SDK and runtime versions to match:
|
||||||
// Linking with d3dx9.lib makes the most recent d3dx9_xx.dll of the
|
// Linking with d3dx9.lib makes the most recent d3dx9_xx.dll of the
|
||||||
// compiler's SDK an actually unnecessary requirement.
|
// compiler's SDK an actually unnecessary requirement.
|
||||||
// Add any d3dx9 functions which you want to use here and load them in LoadD3DX9()
|
// Add any d3dx9 functions which you want to use here and load them in LoadD3DX9()
|
||||||
typedef HRESULT (WINAPI* D3DXSAVESURFACETOFILEATYPE)(LPCSTR, D3DXIMAGE_FILEFORMAT, LPDIRECT3DSURFACE9, CONST PALETTEENTRY*, CONST RECT*);
|
typedef HRESULT (WINAPI* D3DXSAVESURFACETOFILEATYPE)(LPCSTR, D3DXIMAGE_FILEFORMAT, LPDIRECT3DSURFACE9, CONST PALETTEENTRY*, CONST RECT*);
|
||||||
typedef HRESULT (WINAPI* D3DXSAVETEXTURETOFILEATYPE)(LPCSTR, D3DXIMAGE_FILEFORMAT, LPDIRECT3DBASETEXTURE9, CONST PALETTEENTRY*);
|
typedef HRESULT (WINAPI* D3DXSAVETEXTURETOFILEATYPE)(LPCSTR, D3DXIMAGE_FILEFORMAT, LPDIRECT3DBASETEXTURE9, CONST PALETTEENTRY*);
|
||||||
typedef HRESULT (WINAPI* D3DXCOMPILESHADERTYPE)(LPCSTR, UINT, CONST D3DXMACRO*, LPD3DXINCLUDE, LPCSTR, LPCSTR, DWORD, LPD3DXBUFFER*, LPD3DXBUFFER*, LPD3DXCONSTANTTABLE*);
|
typedef HRESULT (WINAPI* D3DXCOMPILESHADERTYPE)(LPCSTR, UINT, CONST D3DXMACRO*, LPD3DXINCLUDE, LPCSTR, LPCSTR, DWORD, LPD3DXBUFFER*, LPD3DXBUFFER*, LPD3DXCONSTANTTABLE*);
|
||||||
|
|
||||||
extern D3DXSAVESURFACETOFILEATYPE PD3DXSaveSurfaceToFileA;
|
extern D3DXSAVESURFACETOFILEATYPE PD3DXSaveSurfaceToFileA;
|
||||||
extern D3DXSAVETEXTURETOFILEATYPE PD3DXSaveTextureToFileA;
|
extern D3DXSAVETEXTURETOFILEATYPE PD3DXSaveTextureToFileA;
|
||||||
extern D3DXCOMPILESHADERTYPE PD3DXCompileShader;
|
extern D3DXCOMPILESHADERTYPE PD3DXCompileShader;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,150 +1,150 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
#include <d3dx9.h>
|
#include <d3dx9.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
#include "DX9_D3DShader.h"
|
#include "DX9_D3DShader.h"
|
||||||
|
|
||||||
namespace DX9
|
namespace DX9
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace D3D
|
namespace D3D
|
||||||
{
|
{
|
||||||
|
|
||||||
// Bytecode->shader.
|
// Bytecode->shader.
|
||||||
LPDIRECT3DVERTEXSHADER9 CreateVertexShaderFromByteCode(const u8 *bytecode, int len)
|
LPDIRECT3DVERTEXSHADER9 CreateVertexShaderFromByteCode(const u8 *bytecode, int len)
|
||||||
{
|
{
|
||||||
LPDIRECT3DVERTEXSHADER9 v_shader;
|
LPDIRECT3DVERTEXSHADER9 v_shader;
|
||||||
HRESULT hr = D3D::dev->CreateVertexShader((DWORD *)bytecode, &v_shader);
|
HRESULT hr = D3D::dev->CreateVertexShader((DWORD *)bytecode, &v_shader);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
v_shader = 0;
|
v_shader = 0;
|
||||||
return v_shader;
|
return v_shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Code->bytecode.
|
// Code->bytecode.
|
||||||
bool CompileVertexShader(const char *code, int len, u8 **bytecode, int *bytecodelen)
|
bool CompileVertexShader(const char *code, int len, u8 **bytecode, int *bytecodelen)
|
||||||
{
|
{
|
||||||
//try to compile
|
//try to compile
|
||||||
LPD3DXBUFFER shaderBuffer = 0;
|
LPD3DXBUFFER shaderBuffer = 0;
|
||||||
LPD3DXBUFFER errorBuffer = 0;
|
LPD3DXBUFFER errorBuffer = 0;
|
||||||
HRESULT hr = PD3DXCompileShader(code, len, 0, 0, "main", D3D::VertexShaderVersionString(),
|
HRESULT hr = PD3DXCompileShader(code, len, 0, 0, "main", D3D::VertexShaderVersionString(),
|
||||||
0, &shaderBuffer, &errorBuffer, 0);
|
0, &shaderBuffer, &errorBuffer, 0);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
//compilation error
|
//compilation error
|
||||||
if (g_ActiveConfig.bShowShaderErrors) {
|
if (g_ActiveConfig.bShowShaderErrors) {
|
||||||
std::string hello = (char*)errorBuffer->GetBufferPointer();
|
std::string hello = (char*)errorBuffer->GetBufferPointer();
|
||||||
hello += "\n\n";
|
hello += "\n\n";
|
||||||
hello += code;
|
hello += code;
|
||||||
MessageBoxA(0, hello.c_str(), "Error compiling vertex shader", MB_ICONERROR);
|
MessageBoxA(0, hello.c_str(), "Error compiling vertex shader", MB_ICONERROR);
|
||||||
}
|
}
|
||||||
*bytecode = 0;
|
*bytecode = 0;
|
||||||
*bytecodelen = 0;
|
*bytecodelen = 0;
|
||||||
}
|
}
|
||||||
else if (SUCCEEDED(hr))
|
else if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
*bytecodelen = shaderBuffer->GetBufferSize();
|
*bytecodelen = shaderBuffer->GetBufferSize();
|
||||||
*bytecode = new u8[*bytecodelen];
|
*bytecode = new u8[*bytecodelen];
|
||||||
memcpy(*bytecode, shaderBuffer->GetBufferPointer(), *bytecodelen);
|
memcpy(*bytecode, shaderBuffer->GetBufferPointer(), *bytecodelen);
|
||||||
}
|
}
|
||||||
|
|
||||||
//cleanup
|
//cleanup
|
||||||
if (shaderBuffer)
|
if (shaderBuffer)
|
||||||
shaderBuffer->Release();
|
shaderBuffer->Release();
|
||||||
if (errorBuffer)
|
if (errorBuffer)
|
||||||
errorBuffer->Release();
|
errorBuffer->Release();
|
||||||
return SUCCEEDED(hr) ? true : false;
|
return SUCCEEDED(hr) ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Bytecode->shader.
|
// Bytecode->shader.
|
||||||
LPDIRECT3DPIXELSHADER9 CreatePixelShaderFromByteCode(const u8 *bytecode, int len)
|
LPDIRECT3DPIXELSHADER9 CreatePixelShaderFromByteCode(const u8 *bytecode, int len)
|
||||||
{
|
{
|
||||||
LPDIRECT3DPIXELSHADER9 p_shader;
|
LPDIRECT3DPIXELSHADER9 p_shader;
|
||||||
HRESULT hr = D3D::dev->CreatePixelShader((DWORD *)bytecode, &p_shader);
|
HRESULT hr = D3D::dev->CreatePixelShader((DWORD *)bytecode, &p_shader);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
p_shader = 0;
|
p_shader = 0;
|
||||||
return p_shader;
|
return p_shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool CompilePixelShader(const char *code, int len, u8 **bytecode, int *bytecodelen)
|
bool CompilePixelShader(const char *code, int len, u8 **bytecode, int *bytecodelen)
|
||||||
{
|
{
|
||||||
LPD3DXBUFFER shaderBuffer = 0;
|
LPD3DXBUFFER shaderBuffer = 0;
|
||||||
LPD3DXBUFFER errorBuffer = 0;
|
LPD3DXBUFFER errorBuffer = 0;
|
||||||
|
|
||||||
// Someone:
|
// Someone:
|
||||||
// For some reason, I had this kind of errors : "Shader uses texture addressing operations
|
// For some reason, I had this kind of errors : "Shader uses texture addressing operations
|
||||||
// in a dependency chain that is too complex for the target shader model (ps_2_0) to handle."
|
// in a dependency chain that is too complex for the target shader model (ps_2_0) to handle."
|
||||||
HRESULT hr = PD3DXCompileShader(code, len, 0, 0, "main", D3D::PixelShaderVersionString(),
|
HRESULT hr = PD3DXCompileShader(code, len, 0, 0, "main", D3D::PixelShaderVersionString(),
|
||||||
0, &shaderBuffer, &errorBuffer, 0);
|
0, &shaderBuffer, &errorBuffer, 0);
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
if (g_ActiveConfig.bShowShaderErrors) {
|
if (g_ActiveConfig.bShowShaderErrors) {
|
||||||
std::string hello = (char*)errorBuffer->GetBufferPointer();
|
std::string hello = (char*)errorBuffer->GetBufferPointer();
|
||||||
hello += "\n\n";
|
hello += "\n\n";
|
||||||
hello += code;
|
hello += code;
|
||||||
MessageBoxA(0, hello.c_str(), "Error compiling pixel shader", MB_ICONERROR);
|
MessageBoxA(0, hello.c_str(), "Error compiling pixel shader", MB_ICONERROR);
|
||||||
}
|
}
|
||||||
*bytecode = 0;
|
*bytecode = 0;
|
||||||
*bytecodelen = 0;
|
*bytecodelen = 0;
|
||||||
}
|
}
|
||||||
else if (SUCCEEDED(hr))
|
else if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
*bytecodelen = shaderBuffer->GetBufferSize();
|
*bytecodelen = shaderBuffer->GetBufferSize();
|
||||||
*bytecode = new u8[*bytecodelen];
|
*bytecode = new u8[*bytecodelen];
|
||||||
memcpy(*bytecode, shaderBuffer->GetBufferPointer(), *bytecodelen);
|
memcpy(*bytecode, shaderBuffer->GetBufferPointer(), *bytecodelen);
|
||||||
}
|
}
|
||||||
|
|
||||||
//cleanup
|
//cleanup
|
||||||
if (shaderBuffer)
|
if (shaderBuffer)
|
||||||
shaderBuffer->Release();
|
shaderBuffer->Release();
|
||||||
if (errorBuffer)
|
if (errorBuffer)
|
||||||
errorBuffer->Release();
|
errorBuffer->Release();
|
||||||
return SUCCEEDED(hr) ? true : false;
|
return SUCCEEDED(hr) ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
LPDIRECT3DVERTEXSHADER9 CompileAndCreateVertexShader(const char *code, int len) {
|
LPDIRECT3DVERTEXSHADER9 CompileAndCreateVertexShader(const char *code, int len) {
|
||||||
u8 *bytecode;
|
u8 *bytecode;
|
||||||
int bytecodelen;
|
int bytecodelen;
|
||||||
if (CompileVertexShader(code, len, &bytecode, &bytecodelen)) {
|
if (CompileVertexShader(code, len, &bytecode, &bytecodelen)) {
|
||||||
LPDIRECT3DVERTEXSHADER9 v_shader = CreateVertexShaderFromByteCode(bytecode, len);
|
LPDIRECT3DVERTEXSHADER9 v_shader = CreateVertexShaderFromByteCode(bytecode, len);
|
||||||
delete [] bytecode;
|
delete [] bytecode;
|
||||||
return v_shader;
|
return v_shader;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LPDIRECT3DPIXELSHADER9 CompileAndCreatePixelShader(const char *code, int len) {
|
LPDIRECT3DPIXELSHADER9 CompileAndCreatePixelShader(const char *code, int len) {
|
||||||
u8 *bytecode;
|
u8 *bytecode;
|
||||||
int bytecodelen;
|
int bytecodelen;
|
||||||
if (CompilePixelShader(code, len, &bytecode, &bytecodelen)) {
|
if (CompilePixelShader(code, len, &bytecode, &bytecodelen)) {
|
||||||
LPDIRECT3DPIXELSHADER9 p_shader = CreatePixelShaderFromByteCode(bytecode, len);
|
LPDIRECT3DPIXELSHADER9 p_shader = CreatePixelShaderFromByteCode(bytecode, len);
|
||||||
delete [] bytecode;
|
delete [] bytecode;
|
||||||
return p_shader;
|
return p_shader;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,39 +1,39 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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
|
#pragma once
|
||||||
|
|
||||||
#include "DX9_D3DBase.h"
|
#include "DX9_D3DBase.h"
|
||||||
|
|
||||||
namespace DX9
|
namespace DX9
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace D3D
|
namespace D3D
|
||||||
{
|
{
|
||||||
LPDIRECT3DVERTEXSHADER9 CreateVertexShaderFromByteCode(const u8 *bytecode, int len);
|
LPDIRECT3DVERTEXSHADER9 CreateVertexShaderFromByteCode(const u8 *bytecode, int len);
|
||||||
LPDIRECT3DPIXELSHADER9 CreatePixelShaderFromByteCode(const u8 *bytecode, int len);
|
LPDIRECT3DPIXELSHADER9 CreatePixelShaderFromByteCode(const u8 *bytecode, int len);
|
||||||
|
|
||||||
// The returned bytecode buffers should be delete[]-d.
|
// The returned bytecode buffers should be delete[]-d.
|
||||||
bool CompileVertexShader(const char *code, int len, u8 **bytecode, int *bytecodelen);
|
bool CompileVertexShader(const char *code, int len, u8 **bytecode, int *bytecodelen);
|
||||||
bool CompilePixelShader(const char *code, int len, u8 **bytecode, int *bytecodelen);
|
bool CompilePixelShader(const char *code, int len, u8 **bytecode, int *bytecodelen);
|
||||||
|
|
||||||
// Utility functions
|
// Utility functions
|
||||||
LPDIRECT3DVERTEXSHADER9 CompileAndCreateVertexShader(const char *code, int len);
|
LPDIRECT3DVERTEXSHADER9 CompileAndCreateVertexShader(const char *code, int len);
|
||||||
LPDIRECT3DPIXELSHADER9 CompileAndCreatePixelShader(const char *code, int len);
|
LPDIRECT3DPIXELSHADER9 CompileAndCreatePixelShader(const char *code, int len);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,275 +1,275 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
#include "DX9_D3DBase.h"
|
#include "DX9_D3DBase.h"
|
||||||
#include "DX9_D3DTexture.h"
|
#include "DX9_D3DTexture.h"
|
||||||
|
|
||||||
namespace DX9
|
namespace DX9
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace D3D
|
namespace D3D
|
||||||
{
|
{
|
||||||
|
|
||||||
LPDIRECT3DTEXTURE9 CreateTexture2D(const u8* buffer, const int width, const int height, const int pitch, D3DFORMAT fmt, bool swap_r_b, int levels)
|
LPDIRECT3DTEXTURE9 CreateTexture2D(const u8* buffer, const int width, const int height, const int pitch, D3DFORMAT fmt, bool swap_r_b, int levels)
|
||||||
{
|
{
|
||||||
u32* pBuffer = (u32*)buffer;
|
u32* pBuffer = (u32*)buffer;
|
||||||
LPDIRECT3DTEXTURE9 pTexture;
|
LPDIRECT3DTEXTURE9 pTexture;
|
||||||
|
|
||||||
// crazy bitmagic, sorry :)
|
// crazy bitmagic, sorry :)
|
||||||
bool isPow2 = !((width&(width-1)) || (height&(height-1)));
|
bool isPow2 = !((width&(width-1)) || (height&(height-1)));
|
||||||
bool bExpand = false;
|
bool bExpand = false;
|
||||||
|
|
||||||
if (fmt == D3DFMT_A8P8) {
|
if (fmt == D3DFMT_A8P8) {
|
||||||
fmt = D3DFMT_A8L8;
|
fmt = D3DFMT_A8L8;
|
||||||
bExpand = true;
|
bExpand = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
// TODO(ector): Allow mipmaps for non-pow textures on newer cards?
|
// TODO(ector): Allow mipmaps for non-pow textures on newer cards?
|
||||||
// TODO(ector): Use the game-specified mipmaps?
|
// TODO(ector): Use the game-specified mipmaps?
|
||||||
if (levels > 0)
|
if (levels > 0)
|
||||||
hr = dev->CreateTexture(width, height, levels, 0, fmt, D3DPOOL_MANAGED, &pTexture, NULL);
|
hr = dev->CreateTexture(width, height, levels, 0, fmt, D3DPOOL_MANAGED, &pTexture, NULL);
|
||||||
else
|
else
|
||||||
hr = dev->CreateTexture(width, height, 0, D3DUSAGE_AUTOGENMIPMAP, fmt, D3DPOOL_MANAGED, &pTexture, NULL);
|
hr = dev->CreateTexture(width, height, 0, D3DUSAGE_AUTOGENMIPMAP, fmt, D3DPOOL_MANAGED, &pTexture, NULL);
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
return 0;
|
return 0;
|
||||||
int level = 0;
|
int level = 0;
|
||||||
D3DLOCKED_RECT Lock;
|
D3DLOCKED_RECT Lock;
|
||||||
pTexture->LockRect(level, &Lock, NULL, 0);
|
pTexture->LockRect(level, &Lock, NULL, 0);
|
||||||
switch (fmt)
|
switch (fmt)
|
||||||
{
|
{
|
||||||
case D3DFMT_L8:
|
case D3DFMT_L8:
|
||||||
case D3DFMT_A8:
|
case D3DFMT_A8:
|
||||||
case D3DFMT_A4L4:
|
case D3DFMT_A4L4:
|
||||||
{
|
{
|
||||||
const u8 *pIn = buffer;
|
const u8 *pIn = buffer;
|
||||||
for (int y = 0; y < height; y++)
|
for (int y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
u8* pBits = ((u8*)Lock.pBits + (y * Lock.Pitch));
|
u8* pBits = ((u8*)Lock.pBits + (y * Lock.Pitch));
|
||||||
memcpy(pBits, pIn, width);
|
memcpy(pBits, pIn, width);
|
||||||
pIn += pitch;
|
pIn += pitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case D3DFMT_R5G6B5:
|
case D3DFMT_R5G6B5:
|
||||||
{
|
{
|
||||||
const u16 *pIn = (u16*)buffer;
|
const u16 *pIn = (u16*)buffer;
|
||||||
for (int y = 0; y < height; y++)
|
for (int y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
u16* pBits = (u16*)((u8*)Lock.pBits + (y * Lock.Pitch));
|
u16* pBits = (u16*)((u8*)Lock.pBits + (y * Lock.Pitch));
|
||||||
memcpy(pBits, pIn, width * 2);
|
memcpy(pBits, pIn, width * 2);
|
||||||
pIn += pitch;
|
pIn += pitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case D3DFMT_A8L8:
|
case D3DFMT_A8L8:
|
||||||
{
|
{
|
||||||
if (bExpand) { // I8
|
if (bExpand) { // I8
|
||||||
const u8 *pIn = buffer;
|
const u8 *pIn = buffer;
|
||||||
// TODO(XK): Find a better way that does not involve either unpacking
|
// TODO(XK): Find a better way that does not involve either unpacking
|
||||||
// or downsampling (i.e. A4L4)
|
// or downsampling (i.e. A4L4)
|
||||||
for (int y = 0; y < height; y++)
|
for (int y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
u8* pBits = ((u8*)Lock.pBits + (y * Lock.Pitch));
|
u8* pBits = ((u8*)Lock.pBits + (y * Lock.Pitch));
|
||||||
for(int i = 0; i < width * 2; i += 2) {
|
for(int i = 0; i < width * 2; i += 2) {
|
||||||
pBits[i] = pIn[i / 2];
|
pBits[i] = pIn[i / 2];
|
||||||
pBits[i + 1] = pIn[i / 2];
|
pBits[i + 1] = pIn[i / 2];
|
||||||
}
|
}
|
||||||
pIn += pitch;
|
pIn += pitch;
|
||||||
}
|
}
|
||||||
} else { // IA8
|
} else { // IA8
|
||||||
const u16 *pIn = (u16*)buffer;
|
const u16 *pIn = (u16*)buffer;
|
||||||
|
|
||||||
for (int y = 0; y < height; y++)
|
for (int y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
u16* pBits = (u16*)((u8*)Lock.pBits + (y * Lock.Pitch));
|
u16* pBits = (u16*)((u8*)Lock.pBits + (y * Lock.Pitch));
|
||||||
memcpy(pBits, pIn, width * 2);
|
memcpy(pBits, pIn, width * 2);
|
||||||
pIn += pitch;
|
pIn += pitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case D3DFMT_A8R8G8B8:
|
case D3DFMT_A8R8G8B8:
|
||||||
{
|
{
|
||||||
if(pitch * 4 == Lock.Pitch && !swap_r_b)
|
if(pitch * 4 == Lock.Pitch && !swap_r_b)
|
||||||
{
|
{
|
||||||
memcpy(Lock.pBits,buffer,Lock.Pitch*height);
|
memcpy(Lock.pBits,buffer,Lock.Pitch*height);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
u32* pIn = pBuffer;
|
u32* pIn = pBuffer;
|
||||||
if (!swap_r_b) {
|
if (!swap_r_b) {
|
||||||
for (int y = 0; y < height; y++)
|
for (int y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
u32 *pBits = (u32*)((u8*)Lock.pBits + (y * Lock.Pitch));
|
u32 *pBits = (u32*)((u8*)Lock.pBits + (y * Lock.Pitch));
|
||||||
memcpy(pBits, pIn, width * 4);
|
memcpy(pBits, pIn, width * 4);
|
||||||
pIn += pitch;
|
pIn += pitch;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int y = 0; y < height; y++)
|
for (int y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
u8 *pIn8 = (u8 *)pIn;
|
u8 *pIn8 = (u8 *)pIn;
|
||||||
u8 *pBits = (u8 *)((u8*)Lock.pBits + (y * Lock.Pitch));
|
u8 *pBits = (u8 *)((u8*)Lock.pBits + (y * Lock.Pitch));
|
||||||
for (int x = 0; x < width * 4; x += 4) {
|
for (int x = 0; x < width * 4; x += 4) {
|
||||||
pBits[x + 0] = pIn8[x + 2];
|
pBits[x + 0] = pIn8[x + 2];
|
||||||
pBits[x + 1] = pIn8[x + 1];
|
pBits[x + 1] = pIn8[x + 1];
|
||||||
pBits[x + 2] = pIn8[x + 0];
|
pBits[x + 2] = pIn8[x + 0];
|
||||||
pBits[x + 3] = pIn8[x + 3];
|
pBits[x + 3] = pIn8[x + 3];
|
||||||
}
|
}
|
||||||
pIn += pitch;
|
pIn += pitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case D3DFMT_DXT1:
|
case D3DFMT_DXT1:
|
||||||
memcpy(Lock.pBits,buffer,((width+3)/4)*((height+3)/4)*8);
|
memcpy(Lock.pBits,buffer,((width+3)/4)*((height+3)/4)*8);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
PanicAlert("D3D: Invalid texture format %i", fmt);
|
PanicAlert("D3D: Invalid texture format %i", fmt);
|
||||||
}
|
}
|
||||||
pTexture->UnlockRect(level);
|
pTexture->UnlockRect(level);
|
||||||
return pTexture;
|
return pTexture;
|
||||||
}
|
}
|
||||||
|
|
||||||
LPDIRECT3DTEXTURE9 CreateOnlyTexture2D(const int width, const int height, D3DFORMAT fmt)
|
LPDIRECT3DTEXTURE9 CreateOnlyTexture2D(const int width, const int height, D3DFORMAT fmt)
|
||||||
{
|
{
|
||||||
LPDIRECT3DTEXTURE9 pTexture;
|
LPDIRECT3DTEXTURE9 pTexture;
|
||||||
// crazy bitmagic, sorry :)
|
// crazy bitmagic, sorry :)
|
||||||
bool isPow2 = !((width&(width-1)) || (height&(height-1)));
|
bool isPow2 = !((width&(width-1)) || (height&(height-1)));
|
||||||
bool bExpand = false;
|
bool bExpand = false;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
// TODO(ector): Allow mipmaps for non-pow textures on newer cards?
|
// TODO(ector): Allow mipmaps for non-pow textures on newer cards?
|
||||||
// TODO(ector): Use the game-specified mipmaps?
|
// TODO(ector): Use the game-specified mipmaps?
|
||||||
if (!isPow2)
|
if (!isPow2)
|
||||||
hr = dev->CreateTexture(width, height, 1, 0, fmt, D3DPOOL_MANAGED, &pTexture, NULL);
|
hr = dev->CreateTexture(width, height, 1, 0, fmt, D3DPOOL_MANAGED, &pTexture, NULL);
|
||||||
else
|
else
|
||||||
hr = dev->CreateTexture(width, height, 0, D3DUSAGE_AUTOGENMIPMAP, fmt, D3DPOOL_MANAGED, &pTexture, NULL);
|
hr = dev->CreateTexture(width, height, 0, D3DUSAGE_AUTOGENMIPMAP, fmt, D3DPOOL_MANAGED, &pTexture, NULL);
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
return 0;
|
return 0;
|
||||||
return pTexture;
|
return pTexture;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReplaceTexture2D(LPDIRECT3DTEXTURE9 pTexture, const u8* buffer, const int width, const int height, const int pitch, D3DFORMAT fmt, bool swap_r_b, int level)
|
void ReplaceTexture2D(LPDIRECT3DTEXTURE9 pTexture, const u8* buffer, const int width, const int height, const int pitch, D3DFORMAT fmt, bool swap_r_b, int level)
|
||||||
{
|
{
|
||||||
u32* pBuffer = (u32*)buffer;
|
u32* pBuffer = (u32*)buffer;
|
||||||
D3DLOCKED_RECT Lock;
|
D3DLOCKED_RECT Lock;
|
||||||
pTexture->LockRect(level, &Lock, NULL, 0);
|
pTexture->LockRect(level, &Lock, NULL, 0);
|
||||||
u32* pIn = pBuffer;
|
u32* pIn = pBuffer;
|
||||||
|
|
||||||
bool bExpand = false;
|
bool bExpand = false;
|
||||||
|
|
||||||
if (fmt == D3DFMT_A8P8) {
|
if (fmt == D3DFMT_A8P8) {
|
||||||
fmt = D3DFMT_A8L8;
|
fmt = D3DFMT_A8L8;
|
||||||
bExpand = true;
|
bExpand = true;
|
||||||
}
|
}
|
||||||
switch (fmt)
|
switch (fmt)
|
||||||
{
|
{
|
||||||
case D3DFMT_A8R8G8B8:
|
case D3DFMT_A8R8G8B8:
|
||||||
if(pitch * 4 == Lock.Pitch && !swap_r_b)
|
if(pitch * 4 == Lock.Pitch && !swap_r_b)
|
||||||
{
|
{
|
||||||
memcpy(Lock.pBits, pBuffer, Lock.Pitch*height);
|
memcpy(Lock.pBits, pBuffer, Lock.Pitch*height);
|
||||||
}
|
}
|
||||||
else if (!swap_r_b)
|
else if (!swap_r_b)
|
||||||
{
|
{
|
||||||
for (int y = 0; y < height; y++)
|
for (int y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
u32 *pBits = (u32*)((u8*)Lock.pBits + (y * Lock.Pitch));
|
u32 *pBits = (u32*)((u8*)Lock.pBits + (y * Lock.Pitch));
|
||||||
memcpy(pBits, pIn, width * 4);
|
memcpy(pBits, pIn, width * 4);
|
||||||
pIn += pitch;
|
pIn += pitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int y = 0; y < height; y++)
|
for (int y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
u8 *pIn8 = (u8 *)pIn;
|
u8 *pIn8 = (u8 *)pIn;
|
||||||
u8 *pBits = (u8 *)((u8*)Lock.pBits + (y * Lock.Pitch));
|
u8 *pBits = (u8 *)((u8*)Lock.pBits + (y * Lock.Pitch));
|
||||||
for (int x = 0; x < width * 4; x += 4)
|
for (int x = 0; x < width * 4; x += 4)
|
||||||
{
|
{
|
||||||
pBits[x + 0] = pIn8[x + 2];
|
pBits[x + 0] = pIn8[x + 2];
|
||||||
pBits[x + 1] = pIn8[x + 1];
|
pBits[x + 1] = pIn8[x + 1];
|
||||||
pBits[x + 2] = pIn8[x + 0];
|
pBits[x + 2] = pIn8[x + 0];
|
||||||
pBits[x + 3] = pIn8[x + 3];
|
pBits[x + 3] = pIn8[x + 3];
|
||||||
}
|
}
|
||||||
pIn += pitch;
|
pIn += pitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case D3DFMT_L8:
|
case D3DFMT_L8:
|
||||||
case D3DFMT_A8:
|
case D3DFMT_A8:
|
||||||
case D3DFMT_A4L4:
|
case D3DFMT_A4L4:
|
||||||
{
|
{
|
||||||
const u8 *pIn = buffer;
|
const u8 *pIn = buffer;
|
||||||
for (int y = 0; y < height; y++)
|
for (int y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
u8* pBits = ((u8*)Lock.pBits + (y * Lock.Pitch));
|
u8* pBits = ((u8*)Lock.pBits + (y * Lock.Pitch));
|
||||||
memcpy(pBits, pIn, width);
|
memcpy(pBits, pIn, width);
|
||||||
pIn += pitch;
|
pIn += pitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case D3DFMT_R5G6B5:
|
case D3DFMT_R5G6B5:
|
||||||
{
|
{
|
||||||
const u16 *pIn = (u16*)buffer;
|
const u16 *pIn = (u16*)buffer;
|
||||||
for (int y = 0; y < height; y++)
|
for (int y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
u16* pBits = (u16*)((u8*)Lock.pBits + (y * Lock.Pitch));
|
u16* pBits = (u16*)((u8*)Lock.pBits + (y * Lock.Pitch));
|
||||||
memcpy(pBits, pIn, width * 2);
|
memcpy(pBits, pIn, width * 2);
|
||||||
pIn += pitch;
|
pIn += pitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case D3DFMT_A8L8:
|
case D3DFMT_A8L8:
|
||||||
{
|
{
|
||||||
if (bExpand) { // I8
|
if (bExpand) { // I8
|
||||||
const u8 *pIn = buffer;
|
const u8 *pIn = buffer;
|
||||||
// TODO(XK): Find a better way that does not involve either unpacking
|
// TODO(XK): Find a better way that does not involve either unpacking
|
||||||
// or downsampling (i.e. A4L4)
|
// or downsampling (i.e. A4L4)
|
||||||
for (int y = 0; y < height; y++)
|
for (int y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
u8* pBits = ((u8*)Lock.pBits + (y * Lock.Pitch));
|
u8* pBits = ((u8*)Lock.pBits + (y * Lock.Pitch));
|
||||||
for(int i = 0; i < width * 2; i += 2) {
|
for(int i = 0; i < width * 2; i += 2) {
|
||||||
pBits[i] = pIn[i / 2];
|
pBits[i] = pIn[i / 2];
|
||||||
pBits[i + 1] = pIn[i / 2];
|
pBits[i + 1] = pIn[i / 2];
|
||||||
}
|
}
|
||||||
pIn += pitch;
|
pIn += pitch;
|
||||||
}
|
}
|
||||||
} else { // IA8
|
} else { // IA8
|
||||||
const u16 *pIn = (u16*)buffer;
|
const u16 *pIn = (u16*)buffer;
|
||||||
|
|
||||||
for (int y = 0; y < height; y++)
|
for (int y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
u16* pBits = (u16*)((u8*)Lock.pBits + (y * Lock.Pitch));
|
u16* pBits = (u16*)((u8*)Lock.pBits + (y * Lock.Pitch));
|
||||||
memcpy(pBits, pIn, width * 2);
|
memcpy(pBits, pIn, width * 2);
|
||||||
pIn += pitch;
|
pIn += pitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case D3DFMT_DXT1:
|
case D3DFMT_DXT1:
|
||||||
memcpy(Lock.pBits,buffer,((width+3)/4)*((height+3)/4)*8);
|
memcpy(Lock.pBits,buffer,((width+3)/4)*((height+3)/4)*8);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
pTexture->UnlockRect(level);
|
pTexture->UnlockRect(level);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,34 +1,34 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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
|
#pragma once
|
||||||
|
|
||||||
#include "DX9_D3DBase.h"
|
#include "DX9_D3DBase.h"
|
||||||
|
|
||||||
namespace DX9
|
namespace DX9
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace D3D
|
namespace D3D
|
||||||
{
|
{
|
||||||
LPDIRECT3DTEXTURE9 CreateTexture2D(const u8* buffer, const int width, const int height, const int pitch, D3DFORMAT fmt = D3DFMT_A8R8G8B8, bool swap_r_b = false, int levels = 1);
|
LPDIRECT3DTEXTURE9 CreateTexture2D(const u8* buffer, const int width, const int height, const int pitch, D3DFORMAT fmt = D3DFMT_A8R8G8B8, bool swap_r_b = false, int levels = 1);
|
||||||
void ReplaceTexture2D(LPDIRECT3DTEXTURE9 pTexture, const u8* buffer, const int width, const int height, const int pitch, D3DFORMAT fmt, bool swap_r_b, int level = 0);
|
void ReplaceTexture2D(LPDIRECT3DTEXTURE9 pTexture, const u8* buffer, const int width, const int height, const int pitch, D3DFORMAT fmt, bool swap_r_b, int level = 0);
|
||||||
LPDIRECT3DTEXTURE9 CreateRenderTarget(const int width, const int height);
|
LPDIRECT3DTEXTURE9 CreateRenderTarget(const int width, const int height);
|
||||||
LPDIRECT3DSURFACE9 CreateDepthStencilSurface(const int width, const int height);
|
LPDIRECT3DSURFACE9 CreateDepthStencilSurface(const int width, const int height);
|
||||||
LPDIRECT3DTEXTURE9 CreateOnlyTexture2D(const int width, const int height, D3DFORMAT fmt);
|
LPDIRECT3DTEXTURE9 CreateOnlyTexture2D(const int width, const int height, D3DFORMAT fmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,447 +1,447 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "StringUtil.h"
|
#include "StringUtil.h"
|
||||||
|
|
||||||
#include "DX9_D3DBase.h"
|
#include "DX9_D3DBase.h"
|
||||||
#include "DX9_D3DUtil.h"
|
#include "DX9_D3DUtil.h"
|
||||||
#include "DX9_Render.h"
|
#include "DX9_Render.h"
|
||||||
|
|
||||||
namespace DX9
|
namespace DX9
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace D3D
|
namespace D3D
|
||||||
{
|
{
|
||||||
|
|
||||||
CD3DFont font;
|
CD3DFont font;
|
||||||
|
|
||||||
#define MAX_NUM_VERTICES 50*6
|
#define MAX_NUM_VERTICES 50*6
|
||||||
struct FONT2DVERTEX {
|
struct FONT2DVERTEX {
|
||||||
float x,y,z;
|
float x,y,z;
|
||||||
float rhw;
|
float rhw;
|
||||||
u32 color;
|
u32 color;
|
||||||
float tu, tv;
|
float tu, tv;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define D3DFVF_FONT2DVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_TEX1)
|
#define D3DFVF_FONT2DVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_TEX1)
|
||||||
#define D3DFVF_FONT3DVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_NORMAL|D3DFVF_TEX1)
|
#define D3DFVF_FONT3DVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_NORMAL|D3DFVF_TEX1)
|
||||||
|
|
||||||
inline FONT2DVERTEX InitFont2DVertex(float x, float y, u32 color, float tu, float tv)
|
inline FONT2DVERTEX InitFont2DVertex(float x, float y, u32 color, float tu, float tv)
|
||||||
{
|
{
|
||||||
FONT2DVERTEX v; v.x=x; v.y=y; v.z=0; v.rhw=1.0f; v.color = color; v.tu = tu; v.tv = tv;
|
FONT2DVERTEX v; v.x=x; v.y=y; v.z=0; v.rhw=1.0f; v.color = color; v.tu = tu; v.tv = tv;
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
CD3DFont::CD3DFont()
|
CD3DFont::CD3DFont()
|
||||||
{
|
{
|
||||||
m_pTexture = NULL;
|
m_pTexture = NULL;
|
||||||
m_pVB = NULL;
|
m_pVB = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum {m_dwTexWidth = 512, m_dwTexHeight = 512};
|
enum {m_dwTexWidth = 512, m_dwTexHeight = 512};
|
||||||
|
|
||||||
int CD3DFont::Init()
|
int CD3DFont::Init()
|
||||||
{
|
{
|
||||||
// Create vertex buffer for the letters
|
// Create vertex buffer for the letters
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
if (FAILED(hr = dev->CreateVertexBuffer(MAX_NUM_VERTICES*sizeof(FONT2DVERTEX),
|
if (FAILED(hr = dev->CreateVertexBuffer(MAX_NUM_VERTICES*sizeof(FONT2DVERTEX),
|
||||||
D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT, &m_pVB, NULL)))
|
D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT, &m_pVB, NULL)))
|
||||||
{
|
{
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
m_fTextScale = 1.0f; // Draw fonts into texture without scaling
|
m_fTextScale = 1.0f; // Draw fonts into texture without scaling
|
||||||
|
|
||||||
// Prepare to create a bitmap
|
// Prepare to create a bitmap
|
||||||
int *pBitmapBits;
|
int *pBitmapBits;
|
||||||
BITMAPINFO bmi;
|
BITMAPINFO bmi;
|
||||||
ZeroMemory(&bmi.bmiHeader, sizeof(BITMAPINFOHEADER));
|
ZeroMemory(&bmi.bmiHeader, sizeof(BITMAPINFOHEADER));
|
||||||
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||||
bmi.bmiHeader.biWidth = (int)m_dwTexWidth;
|
bmi.bmiHeader.biWidth = (int)m_dwTexWidth;
|
||||||
bmi.bmiHeader.biHeight = -(int)m_dwTexHeight;
|
bmi.bmiHeader.biHeight = -(int)m_dwTexHeight;
|
||||||
bmi.bmiHeader.biPlanes = 1;
|
bmi.bmiHeader.biPlanes = 1;
|
||||||
bmi.bmiHeader.biCompression = BI_RGB;
|
bmi.bmiHeader.biCompression = BI_RGB;
|
||||||
bmi.bmiHeader.biBitCount = 32;
|
bmi.bmiHeader.biBitCount = 32;
|
||||||
|
|
||||||
// Create a DC and a bitmap for the font
|
// Create a DC and a bitmap for the font
|
||||||
HDC hDC = CreateCompatibleDC(NULL);
|
HDC hDC = CreateCompatibleDC(NULL);
|
||||||
HBITMAP hbmBitmap = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (VOID**)&pBitmapBits, NULL, 0);
|
HBITMAP hbmBitmap = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (VOID**)&pBitmapBits, NULL, 0);
|
||||||
SetMapMode(hDC, MM_TEXT);
|
SetMapMode(hDC, MM_TEXT);
|
||||||
|
|
||||||
// Create a font. By specifying ANTIALIASED_QUALITY, we might get an
|
// Create a font. By specifying ANTIALIASED_QUALITY, we might get an
|
||||||
// antialiased font, but this is not guaranteed.
|
// antialiased font, but this is not guaranteed.
|
||||||
// We definitely don't want to get it cleartype'd, anyway.
|
// We definitely don't want to get it cleartype'd, anyway.
|
||||||
int m_dwFontHeight = 24;
|
int m_dwFontHeight = 24;
|
||||||
int nHeight = -MulDiv(m_dwFontHeight, int(GetDeviceCaps(hDC, LOGPIXELSY) * m_fTextScale), 72);
|
int nHeight = -MulDiv(m_dwFontHeight, int(GetDeviceCaps(hDC, LOGPIXELSY) * m_fTextScale), 72);
|
||||||
int dwBold = FW_NORMAL; ///FW_BOLD
|
int dwBold = FW_NORMAL; ///FW_BOLD
|
||||||
HFONT hFont = CreateFont(nHeight, 0, 0, 0, dwBold, 0,
|
HFONT hFont = CreateFont(nHeight, 0, 0, 0, dwBold, 0,
|
||||||
FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
|
FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
|
||||||
CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
|
CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
|
||||||
VARIABLE_PITCH, _T("Tahoma"));
|
VARIABLE_PITCH, _T("Tahoma"));
|
||||||
if (NULL == hFont)
|
if (NULL == hFont)
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
|
||||||
HGDIOBJ hOldbmBitmap = SelectObject(hDC, hbmBitmap);
|
HGDIOBJ hOldbmBitmap = SelectObject(hDC, hbmBitmap);
|
||||||
HGDIOBJ hOldFont = SelectObject(hDC, hFont);
|
HGDIOBJ hOldFont = SelectObject(hDC, hFont);
|
||||||
|
|
||||||
// Set text properties
|
// Set text properties
|
||||||
SetTextColor(hDC, 0xFFFFFF);
|
SetTextColor(hDC, 0xFFFFFF);
|
||||||
SetBkColor (hDC, 0);
|
SetBkColor (hDC, 0);
|
||||||
SetTextAlign(hDC, TA_TOP);
|
SetTextAlign(hDC, TA_TOP);
|
||||||
|
|
||||||
// Loop through all printable character and output them to the bitmap..
|
// Loop through all printable character and output them to the bitmap..
|
||||||
// Meanwhile, keep track of the corresponding tex coords for each character.
|
// Meanwhile, keep track of the corresponding tex coords for each character.
|
||||||
int x = 0, y = 0;
|
int x = 0, y = 0;
|
||||||
char str[2] = "\0";
|
char str[2] = "\0";
|
||||||
for (int c = 0; c < 127 - 32; c++)
|
for (int c = 0; c < 127 - 32; c++)
|
||||||
{
|
{
|
||||||
str[0] = c + 32;
|
str[0] = c + 32;
|
||||||
SIZE size;
|
SIZE size;
|
||||||
GetTextExtentPoint32A(hDC, str, 1, &size);
|
GetTextExtentPoint32A(hDC, str, 1, &size);
|
||||||
if ((int)(x+size.cx+1) > m_dwTexWidth)
|
if ((int)(x+size.cx+1) > m_dwTexWidth)
|
||||||
{
|
{
|
||||||
x = 0;
|
x = 0;
|
||||||
y += size.cy + 1;
|
y += size.cy + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExtTextOutA(hDC, x+1, y+0, ETO_OPAQUE | ETO_CLIPPED, NULL, str, 1, NULL);
|
ExtTextOutA(hDC, x+1, y+0, ETO_OPAQUE | ETO_CLIPPED, NULL, str, 1, NULL);
|
||||||
m_fTexCoords[c][0] = ((float)(x+0))/m_dwTexWidth;
|
m_fTexCoords[c][0] = ((float)(x+0))/m_dwTexWidth;
|
||||||
m_fTexCoords[c][1] = ((float)(y+0))/m_dwTexHeight;
|
m_fTexCoords[c][1] = ((float)(y+0))/m_dwTexHeight;
|
||||||
m_fTexCoords[c][2] = ((float)(x+0+size.cx))/m_dwTexWidth;
|
m_fTexCoords[c][2] = ((float)(x+0+size.cx))/m_dwTexWidth;
|
||||||
m_fTexCoords[c][3] = ((float)(y+0+size.cy))/m_dwTexHeight;
|
m_fTexCoords[c][3] = ((float)(y+0+size.cy))/m_dwTexHeight;
|
||||||
|
|
||||||
x += size.cx + 3; //3 to work around annoying ij conflict (part of the j ends up with the i)
|
x += size.cx + 3; //3 to work around annoying ij conflict (part of the j ends up with the i)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new texture for the font
|
// Create a new texture for the font
|
||||||
hr = dev->CreateTexture(m_dwTexWidth, m_dwTexHeight, 1, D3DUSAGE_DYNAMIC,
|
hr = dev->CreateTexture(m_dwTexWidth, m_dwTexHeight, 1, D3DUSAGE_DYNAMIC,
|
||||||
D3DFMT_A4R4G4B4, D3DPOOL_DEFAULT, &m_pTexture, NULL);
|
D3DFMT_A4R4G4B4, D3DPOOL_DEFAULT, &m_pTexture, NULL);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
PanicAlert("Failed to create font texture");
|
PanicAlert("Failed to create font texture");
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lock the surface and write the alpha values for the set pixels
|
// Lock the surface and write the alpha values for the set pixels
|
||||||
D3DLOCKED_RECT d3dlr;
|
D3DLOCKED_RECT d3dlr;
|
||||||
m_pTexture->LockRect(0, &d3dlr, 0, D3DLOCK_DISCARD);
|
m_pTexture->LockRect(0, &d3dlr, 0, D3DLOCK_DISCARD);
|
||||||
int bAlpha; // 4-bit measure of pixel intensity
|
int bAlpha; // 4-bit measure of pixel intensity
|
||||||
|
|
||||||
for (y = 0; y < m_dwTexHeight; y++)
|
for (y = 0; y < m_dwTexHeight; y++)
|
||||||
{
|
{
|
||||||
u16 *pDst16 = (u16*)((u8 *)d3dlr.pBits + y * d3dlr.Pitch);
|
u16 *pDst16 = (u16*)((u8 *)d3dlr.pBits + y * d3dlr.Pitch);
|
||||||
for (x = 0; x < m_dwTexWidth; x++)
|
for (x = 0; x < m_dwTexWidth; x++)
|
||||||
{
|
{
|
||||||
bAlpha = ((pBitmapBits[m_dwTexWidth * y + x] & 0xff) >> 4);
|
bAlpha = ((pBitmapBits[m_dwTexWidth * y + x] & 0xff) >> 4);
|
||||||
pDst16[x] = (bAlpha << 12) | 0x0fff;
|
pDst16[x] = (bAlpha << 12) | 0x0fff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Done updating texture, so clean up used objects
|
// Done updating texture, so clean up used objects
|
||||||
m_pTexture->UnlockRect(0);
|
m_pTexture->UnlockRect(0);
|
||||||
|
|
||||||
SelectObject(hDC, hOldbmBitmap);
|
SelectObject(hDC, hOldbmBitmap);
|
||||||
DeleteObject(hbmBitmap);
|
DeleteObject(hbmBitmap);
|
||||||
|
|
||||||
SelectObject(hDC, hOldFont);
|
SelectObject(hDC, hOldFont);
|
||||||
DeleteObject(hFont);
|
DeleteObject(hFont);
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CD3DFont::Shutdown()
|
int CD3DFont::Shutdown()
|
||||||
{
|
{
|
||||||
m_pVB->Release();
|
m_pVB->Release();
|
||||||
m_pVB = NULL;
|
m_pVB = NULL;
|
||||||
m_pTexture->Release();
|
m_pTexture->Release();
|
||||||
m_pTexture = NULL;
|
m_pTexture = NULL;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const int RS[6][2] =
|
const int RS[6][2] =
|
||||||
{
|
{
|
||||||
{D3DRS_ALPHABLENDENABLE, TRUE},
|
{D3DRS_ALPHABLENDENABLE, TRUE},
|
||||||
{D3DRS_SRCBLEND, D3DBLEND_SRCALPHA},
|
{D3DRS_SRCBLEND, D3DBLEND_SRCALPHA},
|
||||||
{D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA},
|
{D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA},
|
||||||
{D3DRS_CULLMODE, D3DCULL_NONE},
|
{D3DRS_CULLMODE, D3DCULL_NONE},
|
||||||
{D3DRS_ZENABLE, FALSE},
|
{D3DRS_ZENABLE, FALSE},
|
||||||
{D3DRS_FOGENABLE, FALSE},
|
{D3DRS_FOGENABLE, FALSE},
|
||||||
};
|
};
|
||||||
const int TS[6][2] =
|
const int TS[6][2] =
|
||||||
{
|
{
|
||||||
{D3DTSS_COLOROP, D3DTOP_MODULATE},
|
{D3DTSS_COLOROP, D3DTOP_MODULATE},
|
||||||
{D3DTSS_COLORARG1, D3DTA_TEXTURE},
|
{D3DTSS_COLORARG1, D3DTA_TEXTURE},
|
||||||
{D3DTSS_COLORARG2, D3DTA_DIFFUSE },
|
{D3DTSS_COLORARG2, D3DTA_DIFFUSE },
|
||||||
{D3DTSS_ALPHAOP, D3DTOP_MODULATE },
|
{D3DTSS_ALPHAOP, D3DTOP_MODULATE },
|
||||||
{D3DTSS_ALPHAARG1, D3DTA_TEXTURE },
|
{D3DTSS_ALPHAARG1, D3DTA_TEXTURE },
|
||||||
{D3DTSS_ALPHAARG2, D3DTA_DIFFUSE },
|
{D3DTSS_ALPHAARG2, D3DTA_DIFFUSE },
|
||||||
};
|
};
|
||||||
|
|
||||||
static LPDIRECT3DPIXELSHADER9 ps_old = NULL;
|
static LPDIRECT3DPIXELSHADER9 ps_old = NULL;
|
||||||
static LPDIRECT3DVERTEXSHADER9 vs_old = NULL;
|
static LPDIRECT3DVERTEXSHADER9 vs_old = NULL;
|
||||||
|
|
||||||
void RestoreShaders()
|
void RestoreShaders()
|
||||||
{
|
{
|
||||||
D3D::SetTexture(0, 0);
|
D3D::SetTexture(0, 0);
|
||||||
D3D::RefreshVertexDeclaration();
|
D3D::RefreshVertexDeclaration();
|
||||||
D3D::RefreshPixelShader();
|
D3D::RefreshPixelShader();
|
||||||
D3D::RefreshVertexShader();
|
D3D::RefreshVertexShader();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RestoreRenderStates()
|
void RestoreRenderStates()
|
||||||
{
|
{
|
||||||
RestoreShaders();
|
RestoreShaders();
|
||||||
for (int i = 0; i < 6; i++)
|
for (int i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
D3D::RefreshRenderState((_D3DRENDERSTATETYPE)RS[i][0]);
|
D3D::RefreshRenderState((_D3DRENDERSTATETYPE)RS[i][0]);
|
||||||
D3D::RefreshTextureStageState(0, (_D3DTEXTURESTAGESTATETYPE)int(TS[i][0]));
|
D3D::RefreshTextureStageState(0, (_D3DTEXTURESTAGESTATETYPE)int(TS[i][0]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CD3DFont::SetRenderStates()
|
void CD3DFont::SetRenderStates()
|
||||||
{
|
{
|
||||||
D3D::SetTexture(0, m_pTexture);
|
D3D::SetTexture(0, m_pTexture);
|
||||||
|
|
||||||
dev->SetPixelShader(0);
|
dev->SetPixelShader(0);
|
||||||
dev->SetVertexShader(0);
|
dev->SetVertexShader(0);
|
||||||
|
|
||||||
dev->SetFVF(D3DFVF_FONT2DVERTEX);
|
dev->SetFVF(D3DFVF_FONT2DVERTEX);
|
||||||
|
|
||||||
for (int i = 0; i < 6; i++)
|
for (int i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
D3D::ChangeRenderState((_D3DRENDERSTATETYPE)RS[i][0], RS[i][1]);
|
D3D::ChangeRenderState((_D3DRENDERSTATETYPE)RS[i][0], RS[i][1]);
|
||||||
D3D::ChangeTextureStageState(0, (_D3DTEXTURESTAGESTATETYPE)int(TS[i][0]), TS[i][1]);
|
D3D::ChangeTextureStageState(0, (_D3DTEXTURESTAGESTATETYPE)int(TS[i][0]), TS[i][1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int CD3DFont::DrawTextScaled(float x, float y, float fXScale, float fYScale, float spacing, u32 dwColor, const char* strText, bool center)
|
int CD3DFont::DrawTextScaled(float x, float y, float fXScale, float fYScale, float spacing, u32 dwColor, const char* strText, bool center)
|
||||||
{
|
{
|
||||||
if (!m_pVB)
|
if (!m_pVB)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
SetRenderStates();
|
SetRenderStates();
|
||||||
dev->SetStreamSource(0, m_pVB, 0, sizeof(FONT2DVERTEX));
|
dev->SetStreamSource(0, m_pVB, 0, sizeof(FONT2DVERTEX));
|
||||||
|
|
||||||
float vpWidth = 1;
|
float vpWidth = 1;
|
||||||
float vpHeight = 1;
|
float vpHeight = 1;
|
||||||
|
|
||||||
float sx = x*vpWidth-0.5f;
|
float sx = x*vpWidth-0.5f;
|
||||||
float sy = y*vpHeight-0.5f;
|
float sy = y*vpHeight-0.5f;
|
||||||
|
|
||||||
float fStartX = sx;
|
float fStartX = sx;
|
||||||
|
|
||||||
float invLineHeight = 1.0f / ((m_fTexCoords[0][3] - m_fTexCoords[0][1]) * m_dwTexHeight);
|
float invLineHeight = 1.0f / ((m_fTexCoords[0][3] - m_fTexCoords[0][1]) * m_dwTexHeight);
|
||||||
// Fill vertex buffer
|
// Fill vertex buffer
|
||||||
FONT2DVERTEX* pVertices;
|
FONT2DVERTEX* pVertices;
|
||||||
int dwNumTriangles = 0L;
|
int dwNumTriangles = 0L;
|
||||||
m_pVB->Lock(0, 0, (void**)&pVertices, D3DLOCK_DISCARD);
|
m_pVB->Lock(0, 0, (void**)&pVertices, D3DLOCK_DISCARD);
|
||||||
|
|
||||||
const char *oldstrText=strText;
|
const char *oldstrText=strText;
|
||||||
//First, let's measure the text
|
//First, let's measure the text
|
||||||
float tw=0;
|
float tw=0;
|
||||||
float mx=0;
|
float mx=0;
|
||||||
float maxx=0;
|
float maxx=0;
|
||||||
|
|
||||||
while (*strText)
|
while (*strText)
|
||||||
{
|
{
|
||||||
char c = *strText++;
|
char c = *strText++;
|
||||||
|
|
||||||
if (c == ('\n'))
|
if (c == ('\n'))
|
||||||
mx = 0;
|
mx = 0;
|
||||||
if (c < (' '))
|
if (c < (' '))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
float tx1 = m_fTexCoords[c-32][0];
|
float tx1 = m_fTexCoords[c-32][0];
|
||||||
float tx2 = m_fTexCoords[c-32][2];
|
float tx2 = m_fTexCoords[c-32][2];
|
||||||
|
|
||||||
float w = (tx2-tx1)*m_dwTexWidth;
|
float w = (tx2-tx1)*m_dwTexWidth;
|
||||||
w *= (fXScale*vpHeight)*invLineHeight;
|
w *= (fXScale*vpHeight)*invLineHeight;
|
||||||
mx += w + spacing*fXScale*vpWidth;
|
mx += w + spacing*fXScale*vpWidth;
|
||||||
if (mx > maxx) maxx = mx;
|
if (mx > maxx) maxx = mx;
|
||||||
}
|
}
|
||||||
|
|
||||||
float offset = -maxx/2;
|
float offset = -maxx/2;
|
||||||
strText = oldstrText;
|
strText = oldstrText;
|
||||||
//Then let's draw it
|
//Then let's draw it
|
||||||
if (center)
|
if (center)
|
||||||
{
|
{
|
||||||
sx+=offset;
|
sx+=offset;
|
||||||
fStartX+=offset;
|
fStartX+=offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
float wScale = (fXScale*vpHeight)*invLineHeight;
|
float wScale = (fXScale*vpHeight)*invLineHeight;
|
||||||
float hScale = (fYScale*vpHeight)*invLineHeight;
|
float hScale = (fYScale*vpHeight)*invLineHeight;
|
||||||
|
|
||||||
while (*strText)
|
while (*strText)
|
||||||
{
|
{
|
||||||
char c = *strText++;
|
char c = *strText++;
|
||||||
|
|
||||||
if (c == ('\n'))
|
if (c == ('\n'))
|
||||||
{
|
{
|
||||||
sx = fStartX;
|
sx = fStartX;
|
||||||
sy += fYScale*vpHeight;
|
sy += fYScale*vpHeight;
|
||||||
}
|
}
|
||||||
if (c < (' '))
|
if (c < (' '))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
c-=32;
|
c-=32;
|
||||||
float tx1 = m_fTexCoords[c][0];
|
float tx1 = m_fTexCoords[c][0];
|
||||||
float ty1 = m_fTexCoords[c][1];
|
float ty1 = m_fTexCoords[c][1];
|
||||||
float tx2 = m_fTexCoords[c][2];
|
float tx2 = m_fTexCoords[c][2];
|
||||||
float ty2 = m_fTexCoords[c][3];
|
float ty2 = m_fTexCoords[c][3];
|
||||||
|
|
||||||
float w = (tx2-tx1)*m_dwTexWidth;
|
float w = (tx2-tx1)*m_dwTexWidth;
|
||||||
float h = (ty2-ty1)*m_dwTexHeight;
|
float h = (ty2-ty1)*m_dwTexHeight;
|
||||||
|
|
||||||
w *= wScale;
|
w *= wScale;
|
||||||
h *= hScale;
|
h *= hScale;
|
||||||
|
|
||||||
FONT2DVERTEX v[6];
|
FONT2DVERTEX v[6];
|
||||||
v[0] = InitFont2DVertex(sx, sy+h, dwColor, tx1, ty2);
|
v[0] = InitFont2DVertex(sx, sy+h, dwColor, tx1, ty2);
|
||||||
v[1] = InitFont2DVertex(sx, sy, dwColor, tx1, ty1);
|
v[1] = InitFont2DVertex(sx, sy, dwColor, tx1, ty1);
|
||||||
v[2] = InitFont2DVertex(sx+w, sy+h, dwColor, tx2, ty2);
|
v[2] = InitFont2DVertex(sx+w, sy+h, dwColor, tx2, ty2);
|
||||||
v[3] = InitFont2DVertex(sx+w, sy, dwColor, tx2, ty1);
|
v[3] = InitFont2DVertex(sx+w, sy, dwColor, tx2, ty1);
|
||||||
v[4] = v[2];
|
v[4] = v[2];
|
||||||
v[5] = v[1];
|
v[5] = v[1];
|
||||||
|
|
||||||
memcpy(pVertices, v, 6*sizeof(FONT2DVERTEX));
|
memcpy(pVertices, v, 6*sizeof(FONT2DVERTEX));
|
||||||
|
|
||||||
pVertices+=6;
|
pVertices+=6;
|
||||||
dwNumTriangles += 2;
|
dwNumTriangles += 2;
|
||||||
|
|
||||||
if (dwNumTriangles * 3 > (MAX_NUM_VERTICES - 6))
|
if (dwNumTriangles * 3 > (MAX_NUM_VERTICES - 6))
|
||||||
{
|
{
|
||||||
// Unlock, render, and relock the vertex buffer
|
// Unlock, render, and relock the vertex buffer
|
||||||
m_pVB->Unlock();
|
m_pVB->Unlock();
|
||||||
dev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, dwNumTriangles);
|
dev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, dwNumTriangles);
|
||||||
m_pVB->Lock(0, 0, (void**)&pVertices, D3DLOCK_DISCARD);
|
m_pVB->Lock(0, 0, (void**)&pVertices, D3DLOCK_DISCARD);
|
||||||
dwNumTriangles = 0;
|
dwNumTriangles = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
sx += w + spacing*fXScale*vpWidth;
|
sx += w + spacing*fXScale*vpWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unlock and render the vertex buffer
|
// Unlock and render the vertex buffer
|
||||||
m_pVB->Unlock();
|
m_pVB->Unlock();
|
||||||
if (dwNumTriangles > 0)
|
if (dwNumTriangles > 0)
|
||||||
dev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, dwNumTriangles);
|
dev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, dwNumTriangles);
|
||||||
RestoreRenderStates();
|
RestoreRenderStates();
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void quad2d(float x1, float y1, float x2, float y2, u32 color, float u1, float v1, float u2, float v2)
|
void quad2d(float x1, float y1, float x2, float y2, u32 color, float u1, float v1, float u2, float v2)
|
||||||
{
|
{
|
||||||
struct Q2DVertex { float x,y,z,rhw;u32 color;float u,v,w,h; } coords[4] = {
|
struct Q2DVertex { float x,y,z,rhw;u32 color;float u,v,w,h; } coords[4] = {
|
||||||
{x1-0.5f, y1-0.5f, 0, 1, color, u1, v1},
|
{x1-0.5f, y1-0.5f, 0, 1, color, u1, v1},
|
||||||
{x2-0.5f, y1-0.5f, 0, 1, color, u2, v1},
|
{x2-0.5f, y1-0.5f, 0, 1, color, u2, v1},
|
||||||
{x2-0.5f, y2-0.5f, 0, 1, color, u2, v2},
|
{x2-0.5f, y2-0.5f, 0, 1, color, u2, v2},
|
||||||
{x1-0.5f, y2-0.5f, 0, 1, color, u1, v2},
|
{x1-0.5f, y2-0.5f, 0, 1, color, u1, v2},
|
||||||
};
|
};
|
||||||
dev->SetPixelShader(0);
|
dev->SetPixelShader(0);
|
||||||
dev->SetVertexShader(0);
|
dev->SetVertexShader(0);
|
||||||
dev->SetVertexDeclaration(NULL);
|
dev->SetVertexDeclaration(NULL);
|
||||||
dev->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
|
dev->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
|
||||||
dev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, coords, sizeof(Q2DVertex));
|
dev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, coords, sizeof(Q2DVertex));
|
||||||
RestoreShaders();
|
RestoreShaders();
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawShadedTexQuad(IDirect3DTexture9 *texture,
|
void drawShadedTexQuad(IDirect3DTexture9 *texture,
|
||||||
const RECT *rSource,
|
const RECT *rSource,
|
||||||
int SourceWidth,
|
int SourceWidth,
|
||||||
int SourceHeight,
|
int SourceHeight,
|
||||||
int DestWidth,
|
int DestWidth,
|
||||||
int DestHeight,
|
int DestHeight,
|
||||||
IDirect3DPixelShader9 *PShader,
|
IDirect3DPixelShader9 *PShader,
|
||||||
IDirect3DVertexShader9 *Vshader)
|
IDirect3DVertexShader9 *Vshader)
|
||||||
{
|
{
|
||||||
float sw = 1.0f /(float) SourceWidth;
|
float sw = 1.0f /(float) SourceWidth;
|
||||||
float sh = 1.0f /(float) SourceHeight;
|
float sh = 1.0f /(float) SourceHeight;
|
||||||
float dw = 1.0f /(float) DestWidth;
|
float dw = 1.0f /(float) DestWidth;
|
||||||
float dh = 1.0f /(float) DestHeight;
|
float dh = 1.0f /(float) DestHeight;
|
||||||
float u1=((float)rSource->left) * sw;
|
float u1=((float)rSource->left) * sw;
|
||||||
float u2=((float)rSource->right) * sw;
|
float u2=((float)rSource->right) * sw;
|
||||||
float v1=((float)rSource->top) * sh;
|
float v1=((float)rSource->top) * sh;
|
||||||
float v2=((float)rSource->bottom) * sh;
|
float v2=((float)rSource->bottom) * sh;
|
||||||
|
|
||||||
struct Q2DVertex { float x,y,z,rhw,u,v,w,h,L,T,R,B; } coords[4] = {
|
struct Q2DVertex { float x,y,z,rhw,u,v,w,h,L,T,R,B; } coords[4] = {
|
||||||
{-1.0f - dw,-1.0f + dh, 0.0f,1.0f, u1, v2, sw, sh,u1,v1,u2,v2},
|
{-1.0f - dw,-1.0f + dh, 0.0f,1.0f, u1, v2, sw, sh,u1,v1,u2,v2},
|
||||||
{-1.0f - dw, 1.0f + dh, 0.0f,1.0f, u1, v1, sw, sh,u1,v1,u2,v2},
|
{-1.0f - dw, 1.0f + dh, 0.0f,1.0f, u1, v1, sw, sh,u1,v1,u2,v2},
|
||||||
{ 1.0f - dw,-1.0f + dh, 0.0f,1.0f, u2, v2, sw, sh,u1,v1,u2,v2},
|
{ 1.0f - dw,-1.0f + dh, 0.0f,1.0f, u2, v2, sw, sh,u1,v1,u2,v2},
|
||||||
{ 1.0f - dw, 1.0f + dh, 0.0f,1.0f, u2, v1, sw, sh,u1,v1,u2,v2}
|
{ 1.0f - dw, 1.0f + dh, 0.0f,1.0f, u2, v1, sw, sh,u1,v1,u2,v2}
|
||||||
};
|
};
|
||||||
dev->SetVertexShader(Vshader);
|
dev->SetVertexShader(Vshader);
|
||||||
dev->SetPixelShader(PShader);
|
dev->SetPixelShader(PShader);
|
||||||
D3D::SetTexture(0, texture);
|
D3D::SetTexture(0, texture);
|
||||||
dev->SetFVF(D3DFVF_XYZW | D3DFVF_TEX3 | D3DFVF_TEXCOORDSIZE4(2));
|
dev->SetFVF(D3DFVF_XYZW | D3DFVF_TEX3 | D3DFVF_TEXCOORDSIZE4(2));
|
||||||
dev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, coords, sizeof(Q2DVertex));
|
dev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, coords, sizeof(Q2DVertex));
|
||||||
RestoreShaders();
|
RestoreShaders();
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawShadedTexSubQuad(IDirect3DTexture9 *texture,
|
void drawShadedTexSubQuad(IDirect3DTexture9 *texture,
|
||||||
const MathUtil::Rectangle<float> *rSource,
|
const MathUtil::Rectangle<float> *rSource,
|
||||||
int SourceWidth,
|
int SourceWidth,
|
||||||
int SourceHeight,
|
int SourceHeight,
|
||||||
const MathUtil::Rectangle<float> *rDest,
|
const MathUtil::Rectangle<float> *rDest,
|
||||||
int DestWidth,
|
int DestWidth,
|
||||||
int DestHeight,
|
int DestHeight,
|
||||||
IDirect3DPixelShader9 *PShader,
|
IDirect3DPixelShader9 *PShader,
|
||||||
IDirect3DVertexShader9 *Vshader)
|
IDirect3DVertexShader9 *Vshader)
|
||||||
{
|
{
|
||||||
float sw = 1.0f /(float) SourceWidth;
|
float sw = 1.0f /(float) SourceWidth;
|
||||||
float sh = 1.0f /(float) SourceHeight;
|
float sh = 1.0f /(float) SourceHeight;
|
||||||
float dw = 1.0f /(float) DestWidth;
|
float dw = 1.0f /(float) DestWidth;
|
||||||
float dh = 1.0f /(float) DestHeight;
|
float dh = 1.0f /(float) DestHeight;
|
||||||
float u1= rSource->left * sw;
|
float u1= rSource->left * sw;
|
||||||
float u2= rSource->right * sw;
|
float u2= rSource->right * sw;
|
||||||
float v1= rSource->top * sh;
|
float v1= rSource->top * sh;
|
||||||
float v2= rSource->bottom * sh;
|
float v2= rSource->bottom * sh;
|
||||||
|
|
||||||
struct Q2DVertex { float x,y,z,rhw,u,v,w,h,L,T,R,B; } coords[4] = {
|
struct Q2DVertex { float x,y,z,rhw,u,v,w,h,L,T,R,B; } coords[4] = {
|
||||||
{ rDest->left - dw , rDest->top + dh, 1.0f,1.0f, u1, v2, sw, sh,u1,v1,u2,v2},
|
{ rDest->left - dw , rDest->top + dh, 1.0f,1.0f, u1, v2, sw, sh,u1,v1,u2,v2},
|
||||||
{ rDest->left - dw , rDest->bottom + dh, 1.0f,1.0f, u1, v1, sw, sh,u1,v1,u2,v2},
|
{ rDest->left - dw , rDest->bottom + dh, 1.0f,1.0f, u1, v1, sw, sh,u1,v1,u2,v2},
|
||||||
{ rDest->right - dw , rDest->top + dh, 1.0f,1.0f, u2, v2, sw, sh,u1,v1,u2,v2},
|
{ rDest->right - dw , rDest->top + dh, 1.0f,1.0f, u2, v2, sw, sh,u1,v1,u2,v2},
|
||||||
{ rDest->right - dw , rDest->bottom + dh, 1.0f,1.0f, u2, v1, sw, sh,u1,v1,u2,v2}
|
{ rDest->right - dw , rDest->bottom + dh, 1.0f,1.0f, u2, v1, sw, sh,u1,v1,u2,v2}
|
||||||
};
|
};
|
||||||
dev->SetVertexShader(Vshader);
|
dev->SetVertexShader(Vshader);
|
||||||
dev->SetPixelShader(PShader);
|
dev->SetPixelShader(PShader);
|
||||||
D3D::SetTexture(0, texture);
|
D3D::SetTexture(0, texture);
|
||||||
dev->SetFVF(D3DFVF_XYZW | D3DFVF_TEX3 | D3DFVF_TEXCOORDSIZE4(2));
|
dev->SetFVF(D3DFVF_XYZW | D3DFVF_TEX3 | D3DFVF_TEXCOORDSIZE4(2));
|
||||||
dev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, coords, sizeof(Q2DVertex));
|
dev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, coords, sizeof(Q2DVertex));
|
||||||
RestoreShaders();
|
RestoreShaders();
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawClearQuad(u32 Color,float z,IDirect3DPixelShader9 *PShader,IDirect3DVertexShader9 *Vshader)
|
void drawClearQuad(u32 Color,float z,IDirect3DPixelShader9 *PShader,IDirect3DVertexShader9 *Vshader)
|
||||||
{
|
{
|
||||||
struct Q2DVertex { float x,y,z,rhw;u32 color;} coords[4] = {
|
struct Q2DVertex { float x,y,z,rhw;u32 color;} coords[4] = {
|
||||||
{-1.0f, 1.0f, z, 1.0f, Color},
|
{-1.0f, 1.0f, z, 1.0f, Color},
|
||||||
{ 1.0f, 1.0f, z, 1.0f, Color},
|
{ 1.0f, 1.0f, z, 1.0f, Color},
|
||||||
{ 1.0f, -1.0f, z, 1.0f, Color},
|
{ 1.0f, -1.0f, z, 1.0f, Color},
|
||||||
{-1.0f, -1.0f, z, 1.0f, Color}
|
{-1.0f, -1.0f, z, 1.0f, Color}
|
||||||
};
|
};
|
||||||
dev->SetVertexShader(Vshader);
|
dev->SetVertexShader(Vshader);
|
||||||
dev->SetPixelShader(PShader);
|
dev->SetPixelShader(PShader);
|
||||||
dev->SetFVF(D3DFVF_XYZW | D3DFVF_DIFFUSE);
|
dev->SetFVF(D3DFVF_XYZW | D3DFVF_DIFFUSE);
|
||||||
dev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, coords, sizeof(Q2DVertex));
|
dev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, coords, sizeof(Q2DVertex));
|
||||||
RestoreShaders();
|
RestoreShaders();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,88 +1,88 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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
|
#pragma once
|
||||||
|
|
||||||
#include "DX9_D3DBase.h"
|
#include "DX9_D3DBase.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <MathUtil.h>
|
#include <MathUtil.h>
|
||||||
|
|
||||||
namespace DX9
|
namespace DX9
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace D3D
|
namespace D3D
|
||||||
{
|
{
|
||||||
// Font creation flags
|
// Font creation flags
|
||||||
#define D3DFONT_BOLD 0x0001
|
#define D3DFONT_BOLD 0x0001
|
||||||
#define D3DFONT_ITALIC 0x0002
|
#define D3DFONT_ITALIC 0x0002
|
||||||
|
|
||||||
// Font rendering flags
|
// Font rendering flags
|
||||||
#define D3DFONT_CENTERED 0x0001
|
#define D3DFONT_CENTERED 0x0001
|
||||||
|
|
||||||
//a cut-down variant of the DXSDK CD3DFont class
|
//a cut-down variant of the DXSDK CD3DFont class
|
||||||
class CD3DFont
|
class CD3DFont
|
||||||
{
|
{
|
||||||
LPDIRECT3DTEXTURE9 m_pTexture; // The d3d texture for this font
|
LPDIRECT3DTEXTURE9 m_pTexture; // The d3d texture for this font
|
||||||
LPDIRECT3DVERTEXBUFFER9 m_pVB; // VertexBuffer for rendering text
|
LPDIRECT3DVERTEXBUFFER9 m_pVB; // VertexBuffer for rendering text
|
||||||
//int m_dwTexWidth; // Texture dimensions
|
//int m_dwTexWidth; // Texture dimensions
|
||||||
//int m_dwTexHeight;
|
//int m_dwTexHeight;
|
||||||
float m_fTextScale;
|
float m_fTextScale;
|
||||||
float m_fTexCoords[128-32][4];
|
float m_fTexCoords[128-32][4];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CD3DFont();
|
CD3DFont();
|
||||||
// 2D (no longer 3D) text drawing function
|
// 2D (no longer 3D) text drawing function
|
||||||
// Initializing and destroying device-dependent objects
|
// Initializing and destroying device-dependent objects
|
||||||
void SetRenderStates();
|
void SetRenderStates();
|
||||||
int Init();
|
int Init();
|
||||||
int Shutdown();
|
int Shutdown();
|
||||||
int DrawTextScaled( float x, float y,
|
int DrawTextScaled( float x, float y,
|
||||||
float fXScale, float fYScale,
|
float fXScale, float fYScale,
|
||||||
float spacing, u32 dwColor,
|
float spacing, u32 dwColor,
|
||||||
const char* strText, bool center=true );
|
const char* strText, bool center=true );
|
||||||
|
|
||||||
|
|
||||||
// Constructor / destructor
|
// Constructor / destructor
|
||||||
//~CD3DFont();
|
//~CD3DFont();
|
||||||
};
|
};
|
||||||
|
|
||||||
extern CD3DFont font;
|
extern CD3DFont font;
|
||||||
|
|
||||||
void quad2d(float x1, float y1, float x2, float y2, u32 color, float u1=0, float v1=0, float u2=1, float v2=1);
|
void quad2d(float x1, float y1, float x2, float y2, u32 color, float u1=0, float v1=0, float u2=1, float v2=1);
|
||||||
void drawShadedTexQuad(IDirect3DTexture9 *texture,
|
void drawShadedTexQuad(IDirect3DTexture9 *texture,
|
||||||
const RECT *rSource,
|
const RECT *rSource,
|
||||||
int SourceWidth,
|
int SourceWidth,
|
||||||
int SourceHeight,
|
int SourceHeight,
|
||||||
int DestWidth,
|
int DestWidth,
|
||||||
int DestHeight,
|
int DestHeight,
|
||||||
IDirect3DPixelShader9 *PShader,
|
IDirect3DPixelShader9 *PShader,
|
||||||
IDirect3DVertexShader9 *Vshader);
|
IDirect3DVertexShader9 *Vshader);
|
||||||
void drawShadedTexSubQuad(IDirect3DTexture9 *texture,
|
void drawShadedTexSubQuad(IDirect3DTexture9 *texture,
|
||||||
const MathUtil::Rectangle<float> *rSource,
|
const MathUtil::Rectangle<float> *rSource,
|
||||||
int SourceWidth,
|
int SourceWidth,
|
||||||
int SourceHeight,
|
int SourceHeight,
|
||||||
const MathUtil::Rectangle<float> *rDest,
|
const MathUtil::Rectangle<float> *rDest,
|
||||||
int DestWidth,
|
int DestWidth,
|
||||||
int DestHeight,
|
int DestHeight,
|
||||||
IDirect3DPixelShader9 *PShader,
|
IDirect3DPixelShader9 *PShader,
|
||||||
IDirect3DVertexShader9 *Vshader);
|
IDirect3DVertexShader9 *Vshader);
|
||||||
void drawClearQuad(u32 Color,float z,IDirect3DPixelShader9 *PShader,IDirect3DVertexShader9 *Vshader);
|
void drawClearQuad(u32 Color,float z,IDirect3DPixelShader9 *PShader,IDirect3DVertexShader9 *Vshader);
|
||||||
void SaveRenderStates();
|
void SaveRenderStates();
|
||||||
void RestoreRenderStates();
|
void RestoreRenderStates();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,285 +1,285 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
#include "DX9_D3DBase.h"
|
#include "DX9_D3DBase.h"
|
||||||
#include "DX9_Render.h"
|
#include "DX9_Render.h"
|
||||||
#include "DX9_FramebufferManager.h"
|
#include "DX9_FramebufferManager.h"
|
||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
#include "DX9_PixelShaderCache.h"
|
#include "DX9_PixelShaderCache.h"
|
||||||
#include "DX9_VertexShaderCache.h"
|
#include "DX9_VertexShaderCache.h"
|
||||||
#include "DX9_TextureConverter.h"
|
#include "DX9_TextureConverter.h"
|
||||||
|
|
||||||
#include "../Main.h"
|
#include "../Main.h"
|
||||||
|
|
||||||
#undef CHECK
|
#undef CHECK
|
||||||
#define CHECK(hr, Message, ...) if (FAILED(hr)) { PanicAlert(__FUNCTION__ "Failed in %s at line %d: " Message, __FILE__, __LINE__, __VA_ARGS__); }
|
#define CHECK(hr, Message, ...) if (FAILED(hr)) { PanicAlert(__FUNCTION__ "Failed in %s at line %d: " Message, __FILE__, __LINE__, __VA_ARGS__); }
|
||||||
|
|
||||||
namespace DX9
|
namespace DX9
|
||||||
{
|
{
|
||||||
|
|
||||||
XFBSource FramebufferManager::m_realXFBSource;
|
XFBSource FramebufferManager::m_realXFBSource;
|
||||||
|
|
||||||
LPDIRECT3DTEXTURE9 FramebufferManager::s_efb_color_texture;
|
LPDIRECT3DTEXTURE9 FramebufferManager::s_efb_color_texture;
|
||||||
LPDIRECT3DTEXTURE9 FramebufferManager::s_efb_colorRead_texture;
|
LPDIRECT3DTEXTURE9 FramebufferManager::s_efb_colorRead_texture;
|
||||||
LPDIRECT3DTEXTURE9 FramebufferManager::s_efb_depth_texture;
|
LPDIRECT3DTEXTURE9 FramebufferManager::s_efb_depth_texture;
|
||||||
LPDIRECT3DTEXTURE9 FramebufferManager::s_efb_depthRead_texture;
|
LPDIRECT3DTEXTURE9 FramebufferManager::s_efb_depthRead_texture;
|
||||||
|
|
||||||
LPDIRECT3DSURFACE9 FramebufferManager::s_efb_depth_surface;
|
LPDIRECT3DSURFACE9 FramebufferManager::s_efb_depth_surface;
|
||||||
LPDIRECT3DSURFACE9 FramebufferManager::s_efb_color_surface;
|
LPDIRECT3DSURFACE9 FramebufferManager::s_efb_color_surface;
|
||||||
LPDIRECT3DSURFACE9 FramebufferManager::s_efb_color_ReadBuffer;
|
LPDIRECT3DSURFACE9 FramebufferManager::s_efb_color_ReadBuffer;
|
||||||
LPDIRECT3DSURFACE9 FramebufferManager::s_efb_depth_ReadBuffer;
|
LPDIRECT3DSURFACE9 FramebufferManager::s_efb_depth_ReadBuffer;
|
||||||
LPDIRECT3DSURFACE9 FramebufferManager::s_efb_color_OffScreenReadBuffer;
|
LPDIRECT3DSURFACE9 FramebufferManager::s_efb_color_OffScreenReadBuffer;
|
||||||
LPDIRECT3DSURFACE9 FramebufferManager::s_efb_depth_OffScreenReadBuffer;
|
LPDIRECT3DSURFACE9 FramebufferManager::s_efb_depth_OffScreenReadBuffer;
|
||||||
|
|
||||||
D3DFORMAT FramebufferManager::s_efb_color_surface_Format;
|
D3DFORMAT FramebufferManager::s_efb_color_surface_Format;
|
||||||
D3DFORMAT FramebufferManager::s_efb_depth_surface_Format;
|
D3DFORMAT FramebufferManager::s_efb_depth_surface_Format;
|
||||||
D3DFORMAT FramebufferManager::s_efb_depth_ReadBuffer_Format;
|
D3DFORMAT FramebufferManager::s_efb_depth_ReadBuffer_Format;
|
||||||
|
|
||||||
LPDIRECT3DSURFACE9 FramebufferManager::GetEFBColorRTSurface()
|
LPDIRECT3DSURFACE9 FramebufferManager::GetEFBColorRTSurface()
|
||||||
{
|
{
|
||||||
return s_efb_color_surface;
|
return s_efb_color_surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
LPDIRECT3DSURFACE9 FramebufferManager::GetEFBDepthRTSurface()
|
LPDIRECT3DSURFACE9 FramebufferManager::GetEFBDepthRTSurface()
|
||||||
{
|
{
|
||||||
return s_efb_depth_surface;
|
return s_efb_depth_surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
LPDIRECT3DSURFACE9 FramebufferManager::GetEFBColorOffScreenRTSurface()
|
LPDIRECT3DSURFACE9 FramebufferManager::GetEFBColorOffScreenRTSurface()
|
||||||
{
|
{
|
||||||
return s_efb_color_OffScreenReadBuffer;
|
return s_efb_color_OffScreenReadBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
LPDIRECT3DSURFACE9 FramebufferManager::GetEFBDepthOffScreenRTSurface()
|
LPDIRECT3DSURFACE9 FramebufferManager::GetEFBDepthOffScreenRTSurface()
|
||||||
{
|
{
|
||||||
return s_efb_depth_OffScreenReadBuffer;
|
return s_efb_depth_OffScreenReadBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
LPDIRECT3DSURFACE9 FramebufferManager::GetEFBColorReadSurface()
|
LPDIRECT3DSURFACE9 FramebufferManager::GetEFBColorReadSurface()
|
||||||
{
|
{
|
||||||
return s_efb_color_ReadBuffer;
|
return s_efb_color_ReadBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
LPDIRECT3DSURFACE9 FramebufferManager::GetEFBDepthReadSurface()
|
LPDIRECT3DSURFACE9 FramebufferManager::GetEFBDepthReadSurface()
|
||||||
{
|
{
|
||||||
return s_efb_depth_ReadBuffer;
|
return s_efb_depth_ReadBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
D3DFORMAT FramebufferManager::GetEFBDepthRTSurfaceFormat()
|
D3DFORMAT FramebufferManager::GetEFBDepthRTSurfaceFormat()
|
||||||
{
|
{
|
||||||
return s_efb_depth_surface_Format;
|
return s_efb_depth_surface_Format;
|
||||||
}
|
}
|
||||||
|
|
||||||
D3DFORMAT FramebufferManager::GetEFBDepthReadSurfaceFormat()
|
D3DFORMAT FramebufferManager::GetEFBDepthReadSurfaceFormat()
|
||||||
{
|
{
|
||||||
return s_efb_depth_ReadBuffer_Format;
|
return s_efb_depth_ReadBuffer_Format;
|
||||||
}
|
}
|
||||||
|
|
||||||
D3DFORMAT FramebufferManager::GetEFBColorRTSurfaceFormat()
|
D3DFORMAT FramebufferManager::GetEFBColorRTSurfaceFormat()
|
||||||
{
|
{
|
||||||
return s_efb_color_surface_Format;
|
return s_efb_color_surface_Format;
|
||||||
}
|
}
|
||||||
|
|
||||||
LPDIRECT3DTEXTURE9 FramebufferManager::GetEFBColorTexture(const EFBRectangle& sourceRc)
|
LPDIRECT3DTEXTURE9 FramebufferManager::GetEFBColorTexture(const EFBRectangle& sourceRc)
|
||||||
{
|
{
|
||||||
return s_efb_color_texture;
|
return s_efb_color_texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
LPDIRECT3DTEXTURE9 FramebufferManager::GetEFBDepthTexture(const EFBRectangle &sourceRc)
|
LPDIRECT3DTEXTURE9 FramebufferManager::GetEFBDepthTexture(const EFBRectangle &sourceRc)
|
||||||
{
|
{
|
||||||
return s_efb_depth_texture;
|
return s_efb_depth_texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
FramebufferManager::FramebufferManager()
|
FramebufferManager::FramebufferManager()
|
||||||
{
|
{
|
||||||
s_efb_color_texture = NULL;
|
s_efb_color_texture = NULL;
|
||||||
LPDIRECT3DTEXTURE9 s_efb_colorRead_texture = NULL;
|
LPDIRECT3DTEXTURE9 s_efb_colorRead_texture = NULL;
|
||||||
LPDIRECT3DTEXTURE9 s_efb_depth_texture = NULL;
|
LPDIRECT3DTEXTURE9 s_efb_depth_texture = NULL;
|
||||||
LPDIRECT3DTEXTURE9 s_efb_depthRead_texture = NULL;
|
LPDIRECT3DTEXTURE9 s_efb_depthRead_texture = NULL;
|
||||||
|
|
||||||
LPDIRECT3DSURFACE9 s_efb_depth_surface = NULL;
|
LPDIRECT3DSURFACE9 s_efb_depth_surface = NULL;
|
||||||
LPDIRECT3DSURFACE9 s_efb_color_surface = NULL;
|
LPDIRECT3DSURFACE9 s_efb_color_surface = NULL;
|
||||||
LPDIRECT3DSURFACE9 s_efb_color_ReadBuffer = NULL;
|
LPDIRECT3DSURFACE9 s_efb_color_ReadBuffer = NULL;
|
||||||
LPDIRECT3DSURFACE9 s_efb_depth_ReadBuffer = NULL;
|
LPDIRECT3DSURFACE9 s_efb_depth_ReadBuffer = NULL;
|
||||||
LPDIRECT3DSURFACE9 s_efb_color_OffScreenReadBuffer = NULL;
|
LPDIRECT3DSURFACE9 s_efb_color_OffScreenReadBuffer = NULL;
|
||||||
LPDIRECT3DSURFACE9 s_efb_depth_OffScreenReadBuffer = NULL;
|
LPDIRECT3DSURFACE9 s_efb_depth_OffScreenReadBuffer = NULL;
|
||||||
|
|
||||||
D3DFORMAT s_efb_color_surface_Format = D3DFMT_FORCE_DWORD;
|
D3DFORMAT s_efb_color_surface_Format = D3DFMT_FORCE_DWORD;
|
||||||
D3DFORMAT s_efb_depth_surface_Format = D3DFMT_FORCE_DWORD;
|
D3DFORMAT s_efb_depth_surface_Format = D3DFMT_FORCE_DWORD;
|
||||||
D3DFORMAT s_efb_depth_ReadBuffer_Format = D3DFMT_FORCE_DWORD;
|
D3DFORMAT s_efb_depth_ReadBuffer_Format = D3DFMT_FORCE_DWORD;
|
||||||
m_realXFBSource.texture = NULL;
|
m_realXFBSource.texture = NULL;
|
||||||
|
|
||||||
// Simplest possible setup to start with.
|
// Simplest possible setup to start with.
|
||||||
int target_width = Renderer::GetFullTargetWidth();
|
int target_width = Renderer::GetFullTargetWidth();
|
||||||
int target_height = Renderer::GetFullTargetHeight();
|
int target_height = Renderer::GetFullTargetHeight();
|
||||||
|
|
||||||
s_efb_color_surface_Format = D3DFMT_A8R8G8B8;
|
s_efb_color_surface_Format = D3DFMT_A8R8G8B8;
|
||||||
// Get the framebuffer texture
|
// Get the framebuffer texture
|
||||||
HRESULT hr = D3D::dev->CreateTexture(target_width, target_height, 1, D3DUSAGE_RENDERTARGET, s_efb_color_surface_Format,
|
HRESULT hr = D3D::dev->CreateTexture(target_width, target_height, 1, D3DUSAGE_RENDERTARGET, s_efb_color_surface_Format,
|
||||||
D3DPOOL_DEFAULT, &s_efb_color_texture, NULL);
|
D3DPOOL_DEFAULT, &s_efb_color_texture, NULL);
|
||||||
if(s_efb_color_texture)
|
if(s_efb_color_texture)
|
||||||
{
|
{
|
||||||
hr = s_efb_color_texture->GetSurfaceLevel(0, &s_efb_color_surface);
|
hr = s_efb_color_texture->GetSurfaceLevel(0, &s_efb_color_surface);
|
||||||
}
|
}
|
||||||
CHECK(hr, "Create color texture (size: %dx%d; hr=%#x)", target_width, target_height, hr);
|
CHECK(hr, "Create color texture (size: %dx%d; hr=%#x)", target_width, target_height, hr);
|
||||||
hr = D3D::dev->CreateTexture(1, 1, 1, D3DUSAGE_RENDERTARGET, s_efb_color_surface_Format,
|
hr = D3D::dev->CreateTexture(1, 1, 1, D3DUSAGE_RENDERTARGET, s_efb_color_surface_Format,
|
||||||
D3DPOOL_DEFAULT, &s_efb_colorRead_texture, NULL);
|
D3DPOOL_DEFAULT, &s_efb_colorRead_texture, NULL);
|
||||||
CHECK(hr, "Create Color Read Texture (hr=%#x)", hr);
|
CHECK(hr, "Create Color Read Texture (hr=%#x)", hr);
|
||||||
if(s_efb_colorRead_texture)
|
if(s_efb_colorRead_texture)
|
||||||
{
|
{
|
||||||
s_efb_colorRead_texture->GetSurfaceLevel(0, &s_efb_color_ReadBuffer);
|
s_efb_colorRead_texture->GetSurfaceLevel(0, &s_efb_color_ReadBuffer);
|
||||||
}
|
}
|
||||||
// Create an offscreen surface that we can lock to retrieve the data
|
// Create an offscreen surface that we can lock to retrieve the data
|
||||||
hr = D3D::dev->CreateOffscreenPlainSurface(1, 1, s_efb_color_surface_Format, D3DPOOL_SYSTEMMEM, &s_efb_color_OffScreenReadBuffer, NULL);
|
hr = D3D::dev->CreateOffscreenPlainSurface(1, 1, s_efb_color_surface_Format, D3DPOOL_SYSTEMMEM, &s_efb_color_OffScreenReadBuffer, NULL);
|
||||||
CHECK(hr, "Create offscreen color surface (hr=%#x)", hr);
|
CHECK(hr, "Create offscreen color surface (hr=%#x)", hr);
|
||||||
|
|
||||||
// Select a Z-buffer format with hardware support
|
// Select a Z-buffer format with hardware support
|
||||||
D3DFORMAT *DepthTexFormats = new D3DFORMAT[5];
|
D3DFORMAT *DepthTexFormats = new D3DFORMAT[5];
|
||||||
DepthTexFormats[0] = FOURCC_INTZ;
|
DepthTexFormats[0] = FOURCC_INTZ;
|
||||||
DepthTexFormats[1] = FOURCC_DF24;
|
DepthTexFormats[1] = FOURCC_DF24;
|
||||||
DepthTexFormats[2] = FOURCC_RAWZ;
|
DepthTexFormats[2] = FOURCC_RAWZ;
|
||||||
DepthTexFormats[3] = FOURCC_DF16;
|
DepthTexFormats[3] = FOURCC_DF16;
|
||||||
DepthTexFormats[4] = D3DFMT_D24X8;
|
DepthTexFormats[4] = D3DFMT_D24X8;
|
||||||
|
|
||||||
for(int i = 0; i < 5; i++)
|
for(int i = 0; i < 5; i++)
|
||||||
{
|
{
|
||||||
s_efb_depth_surface_Format = DepthTexFormats[i];
|
s_efb_depth_surface_Format = DepthTexFormats[i];
|
||||||
// Create the framebuffer depth texture
|
// Create the framebuffer depth texture
|
||||||
hr = D3D::dev->CreateTexture(target_width, target_height, 1, D3DUSAGE_DEPTHSTENCIL, s_efb_depth_surface_Format,
|
hr = D3D::dev->CreateTexture(target_width, target_height, 1, D3DUSAGE_DEPTHSTENCIL, s_efb_depth_surface_Format,
|
||||||
D3DPOOL_DEFAULT, &s_efb_depth_texture, NULL);
|
D3DPOOL_DEFAULT, &s_efb_depth_texture, NULL);
|
||||||
if (!FAILED(hr))
|
if (!FAILED(hr))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
CHECK(hr, "Framebuffer depth texture (size: %dx%d; hr=%#x)", target_width, target_height, hr);
|
CHECK(hr, "Framebuffer depth texture (size: %dx%d; hr=%#x)", target_width, target_height, hr);
|
||||||
// Get the Surface
|
// Get the Surface
|
||||||
if(s_efb_depth_texture)
|
if(s_efb_depth_texture)
|
||||||
{
|
{
|
||||||
s_efb_depth_texture->GetSurfaceLevel(0, &s_efb_depth_surface);
|
s_efb_depth_texture->GetSurfaceLevel(0, &s_efb_depth_surface);
|
||||||
}
|
}
|
||||||
// Create a 4x4 pixel texture to work as a buffer for peeking
|
// Create a 4x4 pixel texture to work as a buffer for peeking
|
||||||
if(s_efb_depth_surface_Format == FOURCC_RAWZ || s_efb_depth_surface_Format == D3DFMT_D24X8)
|
if(s_efb_depth_surface_Format == FOURCC_RAWZ || s_efb_depth_surface_Format == D3DFMT_D24X8)
|
||||||
{
|
{
|
||||||
DepthTexFormats[0] = D3DFMT_A8R8G8B8;
|
DepthTexFormats[0] = D3DFMT_A8R8G8B8;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DepthTexFormats[0] = D3DFMT_R32F;
|
DepthTexFormats[0] = D3DFMT_R32F;
|
||||||
}
|
}
|
||||||
DepthTexFormats[1] = D3DFMT_A8R8G8B8;
|
DepthTexFormats[1] = D3DFMT_A8R8G8B8;
|
||||||
|
|
||||||
for(int i = 0; i < 2; i++)
|
for(int i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
s_efb_depth_ReadBuffer_Format = DepthTexFormats[i];
|
s_efb_depth_ReadBuffer_Format = DepthTexFormats[i];
|
||||||
// Get the framebuffer Depth texture
|
// Get the framebuffer Depth texture
|
||||||
hr = D3D::dev->CreateTexture(4, 4, 1, D3DUSAGE_RENDERTARGET, s_efb_depth_ReadBuffer_Format,
|
hr = D3D::dev->CreateTexture(4, 4, 1, D3DUSAGE_RENDERTARGET, s_efb_depth_ReadBuffer_Format,
|
||||||
D3DPOOL_DEFAULT, &s_efb_depthRead_texture, NULL);
|
D3DPOOL_DEFAULT, &s_efb_depthRead_texture, NULL);
|
||||||
if (!FAILED(hr))
|
if (!FAILED(hr))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
CHECK(hr, "Create depth read texture (hr=%#x)", hr);
|
CHECK(hr, "Create depth read texture (hr=%#x)", hr);
|
||||||
if(s_efb_depthRead_texture)
|
if(s_efb_depthRead_texture)
|
||||||
{
|
{
|
||||||
s_efb_depthRead_texture->GetSurfaceLevel(0, &s_efb_depth_ReadBuffer);
|
s_efb_depthRead_texture->GetSurfaceLevel(0, &s_efb_depth_ReadBuffer);
|
||||||
}
|
}
|
||||||
// Create an offscreen surface that we can lock to retrieve the data
|
// Create an offscreen surface that we can lock to retrieve the data
|
||||||
hr = D3D::dev->CreateOffscreenPlainSurface(4, 4, s_efb_depth_ReadBuffer_Format, D3DPOOL_SYSTEMMEM, &s_efb_depth_OffScreenReadBuffer, NULL);
|
hr = D3D::dev->CreateOffscreenPlainSurface(4, 4, s_efb_depth_ReadBuffer_Format, D3DPOOL_SYSTEMMEM, &s_efb_depth_OffScreenReadBuffer, NULL);
|
||||||
CHECK(hr, "Create depth offscreen surface (hr=%#x)", hr);
|
CHECK(hr, "Create depth offscreen surface (hr=%#x)", hr);
|
||||||
delete [] DepthTexFormats;
|
delete [] DepthTexFormats;
|
||||||
}
|
}
|
||||||
|
|
||||||
FramebufferManager::~FramebufferManager()
|
FramebufferManager::~FramebufferManager()
|
||||||
{
|
{
|
||||||
SAFE_RELEASE(s_efb_depth_surface);
|
SAFE_RELEASE(s_efb_depth_surface);
|
||||||
SAFE_RELEASE(s_efb_color_surface);
|
SAFE_RELEASE(s_efb_color_surface);
|
||||||
SAFE_RELEASE(s_efb_color_ReadBuffer);
|
SAFE_RELEASE(s_efb_color_ReadBuffer);
|
||||||
SAFE_RELEASE(s_efb_depth_ReadBuffer);
|
SAFE_RELEASE(s_efb_depth_ReadBuffer);
|
||||||
SAFE_RELEASE(s_efb_color_OffScreenReadBuffer);
|
SAFE_RELEASE(s_efb_color_OffScreenReadBuffer);
|
||||||
SAFE_RELEASE(s_efb_depth_OffScreenReadBuffer);
|
SAFE_RELEASE(s_efb_depth_OffScreenReadBuffer);
|
||||||
SAFE_RELEASE(s_efb_color_texture);
|
SAFE_RELEASE(s_efb_color_texture);
|
||||||
SAFE_RELEASE(s_efb_colorRead_texture);
|
SAFE_RELEASE(s_efb_colorRead_texture);
|
||||||
SAFE_RELEASE(s_efb_depth_texture);
|
SAFE_RELEASE(s_efb_depth_texture);
|
||||||
SAFE_RELEASE(s_efb_depthRead_texture);
|
SAFE_RELEASE(s_efb_depthRead_texture);
|
||||||
|
|
||||||
if (m_realXFBSource.texture)
|
if (m_realXFBSource.texture)
|
||||||
m_realXFBSource.texture->Release();
|
m_realXFBSource.texture->Release();
|
||||||
m_realXFBSource.texture = NULL;
|
m_realXFBSource.texture = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramebufferManager::copyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
|
void FramebufferManager::copyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
|
||||||
{
|
{
|
||||||
// TODO:
|
// TODO:
|
||||||
|
|
||||||
//u8* xfb_in_ram = Memory_GetPtr(xfbAddr);
|
//u8* xfb_in_ram = Memory_GetPtr(xfbAddr);
|
||||||
//if (!xfb_in_ram)
|
//if (!xfb_in_ram)
|
||||||
//{
|
//{
|
||||||
// WARN_LOG(VIDEO, "Tried to copy to invalid XFB address");
|
// WARN_LOG(VIDEO, "Tried to copy to invalid XFB address");
|
||||||
// return;
|
// return;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//TargetRectangle targetRc = Renderer::ConvertEFBRectangle(sourceRc);
|
//TargetRectangle targetRc = Renderer::ConvertEFBRectangle(sourceRc);
|
||||||
//TextureConverter::EncodeToRamYUYV(GetEFBColorTexture(sourceRc), targetRc, xfb_in_ram, fbWidth, fbHeight);
|
//TextureConverter::EncodeToRamYUYV(GetEFBColorTexture(sourceRc), targetRc, xfb_in_ram, fbWidth, fbHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
const XFBSource** FramebufferManager::getRealXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount)
|
const XFBSource** FramebufferManager::getRealXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
//xfbCount = 1;
|
//xfbCount = 1;
|
||||||
|
|
||||||
//m_realXFBSource.texWidth = fbWidth;
|
//m_realXFBSource.texWidth = fbWidth;
|
||||||
//m_realXFBSource.texHeight = fbHeight;
|
//m_realXFBSource.texHeight = fbHeight;
|
||||||
|
|
||||||
//m_realXFBSource.srcAddr = xfbAddr;
|
//m_realXFBSource.srcAddr = xfbAddr;
|
||||||
//m_realXFBSource.srcWidth = fbWidth;
|
//m_realXFBSource.srcWidth = fbWidth;
|
||||||
//m_realXFBSource.srcHeight = fbHeight;
|
//m_realXFBSource.srcHeight = fbHeight;
|
||||||
|
|
||||||
//if (!m_realXFBSource.texture)
|
//if (!m_realXFBSource.texture)
|
||||||
//{
|
//{
|
||||||
// D3D::dev->CreateTexture(fbWidth, fbHeight, 1, D3DUSAGE_RENDERTARGET, s_efb_color_surface_Format,
|
// D3D::dev->CreateTexture(fbWidth, fbHeight, 1, D3DUSAGE_RENDERTARGET, s_efb_color_surface_Format,
|
||||||
// D3DPOOL_DEFAULT, &m_realXFBSource.texture, NULL);
|
// D3DPOOL_DEFAULT, &m_realXFBSource.texture, NULL);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//// Decode YUYV data from GameCube RAM
|
//// Decode YUYV data from GameCube RAM
|
||||||
//TextureConverter::DecodeToTexture(xfbAddr, fbWidth, fbHeight, m_realXFBSource.texture);
|
//TextureConverter::DecodeToTexture(xfbAddr, fbWidth, fbHeight, m_realXFBSource.texture);
|
||||||
|
|
||||||
//m_overlappingXFBArray[0] = &m_realXFBSource;
|
//m_overlappingXFBArray[0] = &m_realXFBSource;
|
||||||
|
|
||||||
//return &m_overlappingXFBArray[0];
|
//return &m_overlappingXFBArray[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
XFBSourceBase *FramebufferManager::CreateXFBSource(unsigned int target_width, unsigned int target_height)
|
XFBSourceBase *FramebufferManager::CreateXFBSource(unsigned int target_width, unsigned int target_height)
|
||||||
{
|
{
|
||||||
XFBSource* const xfbs = new XFBSource;
|
XFBSource* const xfbs = new XFBSource;
|
||||||
D3D::dev->CreateTexture(target_width, target_height, 1, D3DUSAGE_RENDERTARGET, s_efb_color_surface_Format,
|
D3D::dev->CreateTexture(target_width, target_height, 1, D3DUSAGE_RENDERTARGET, s_efb_color_surface_Format,
|
||||||
D3DPOOL_DEFAULT, &xfbs->texture, NULL);
|
D3DPOOL_DEFAULT, &xfbs->texture, NULL);
|
||||||
|
|
||||||
return xfbs;
|
return xfbs;
|
||||||
}
|
}
|
||||||
|
|
||||||
XFBSource::~XFBSource()
|
XFBSource::~XFBSource()
|
||||||
{
|
{
|
||||||
texture->Release();
|
texture->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
void XFBSource::CopyEFB(const TargetRectangle& efbSource)
|
void XFBSource::CopyEFB(const TargetRectangle& efbSource)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,130 +1,130 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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/
|
||||||
|
|
||||||
#ifndef _FRAMEBUFFERMANAGER_D3D_H_
|
#ifndef _FRAMEBUFFERMANAGER_D3D_H_
|
||||||
#define _FRAMEBUFFERMANAGER_D3D_H_
|
#define _FRAMEBUFFERMANAGER_D3D_H_
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include "DX9_D3DBase.h"
|
#include "DX9_D3DBase.h"
|
||||||
|
|
||||||
#include "../FramebufferManager.h"
|
#include "../FramebufferManager.h"
|
||||||
|
|
||||||
// On the GameCube, the game sends a request for the graphics processor to
|
// On the GameCube, the game sends a request for the graphics processor to
|
||||||
// transfer its internal EFB (Embedded Framebuffer) to an area in GameCube RAM
|
// transfer its internal EFB (Embedded Framebuffer) to an area in GameCube RAM
|
||||||
// called the XFB (External Framebuffer). The size and location of the XFB is
|
// called the XFB (External Framebuffer). The size and location of the XFB is
|
||||||
// decided at the time of the copy, and the format is always YUYV. The video
|
// decided at the time of the copy, and the format is always YUYV. The video
|
||||||
// interface is given a pointer to the XFB, which will be decoded and
|
// interface is given a pointer to the XFB, which will be decoded and
|
||||||
// displayed on the TV.
|
// displayed on the TV.
|
||||||
//
|
//
|
||||||
// There are two ways for Dolphin to emulate this:
|
// There are two ways for Dolphin to emulate this:
|
||||||
//
|
//
|
||||||
// Real XFB mode:
|
// Real XFB mode:
|
||||||
//
|
//
|
||||||
// Dolphin will behave like the GameCube and encode the EFB to
|
// Dolphin will behave like the GameCube and encode the EFB to
|
||||||
// a portion of GameCube RAM. The emulated video interface will decode the data
|
// a portion of GameCube RAM. The emulated video interface will decode the data
|
||||||
// for output to the screen.
|
// for output to the screen.
|
||||||
//
|
//
|
||||||
// Advantages: Behaves exactly like the GameCube.
|
// Advantages: Behaves exactly like the GameCube.
|
||||||
// Disadvantages: Resolution will be limited.
|
// Disadvantages: Resolution will be limited.
|
||||||
//
|
//
|
||||||
// Virtual XFB mode:
|
// Virtual XFB mode:
|
||||||
//
|
//
|
||||||
// When a request is made to copy the EFB to an XFB, Dolphin
|
// When a request is made to copy the EFB to an XFB, Dolphin
|
||||||
// will remember the RAM location and size of the XFB in a Virtual XFB list.
|
// will remember the RAM location and size of the XFB in a Virtual XFB list.
|
||||||
// The video interface will look up the XFB in the list and use the enhanced
|
// The video interface will look up the XFB in the list and use the enhanced
|
||||||
// data stored there, if available.
|
// data stored there, if available.
|
||||||
//
|
//
|
||||||
// Advantages: Enables high resolution graphics, better than real hardware.
|
// Advantages: Enables high resolution graphics, better than real hardware.
|
||||||
// Disadvantages: If the GameCube CPU writes directly to the XFB (which is
|
// Disadvantages: If the GameCube CPU writes directly to the XFB (which is
|
||||||
// possible but uncommon), the Virtual XFB will not capture this information.
|
// possible but uncommon), the Virtual XFB will not capture this information.
|
||||||
|
|
||||||
// There may be multiple XFBs in GameCube RAM. This is the maximum number to
|
// There may be multiple XFBs in GameCube RAM. This is the maximum number to
|
||||||
// virtualize.
|
// virtualize.
|
||||||
|
|
||||||
namespace DX9
|
namespace DX9
|
||||||
{
|
{
|
||||||
|
|
||||||
const int MAX_VIRTUAL_XFB = 8;
|
const int MAX_VIRTUAL_XFB = 8;
|
||||||
|
|
||||||
inline bool addrRangesOverlap(u32 aLower, u32 aUpper, u32 bLower, u32 bUpper)
|
inline bool addrRangesOverlap(u32 aLower, u32 aUpper, u32 bLower, u32 bUpper)
|
||||||
{
|
{
|
||||||
return !((aLower >= bUpper) || (bLower >= aUpper));
|
return !((aLower >= bUpper) || (bLower >= aUpper));
|
||||||
}
|
}
|
||||||
|
|
||||||
struct XFBSource : public XFBSourceBase
|
struct XFBSource : public XFBSourceBase
|
||||||
{
|
{
|
||||||
XFBSource() : texture(NULL) {}
|
XFBSource() : texture(NULL) {}
|
||||||
~XFBSource();
|
~XFBSource();
|
||||||
|
|
||||||
void CopyEFB(const TargetRectangle& efbSource);
|
void CopyEFB(const TargetRectangle& efbSource);
|
||||||
|
|
||||||
LPDIRECT3DTEXTURE9 texture;
|
LPDIRECT3DTEXTURE9 texture;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FramebufferManager : public ::FramebufferManagerBase
|
class FramebufferManager : public ::FramebufferManagerBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FramebufferManager();
|
FramebufferManager();
|
||||||
~FramebufferManager();
|
~FramebufferManager();
|
||||||
|
|
||||||
void CopyToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc);
|
void CopyToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc);
|
||||||
|
|
||||||
XFBSourceBase *CreateXFBSource(unsigned int target_width, unsigned int target_height);
|
XFBSourceBase *CreateXFBSource(unsigned int target_width, unsigned int target_height);
|
||||||
|
|
||||||
static LPDIRECT3DTEXTURE9 GetEFBColorTexture(const EFBRectangle& sourceRc);
|
static LPDIRECT3DTEXTURE9 GetEFBColorTexture(const EFBRectangle& sourceRc);
|
||||||
static LPDIRECT3DTEXTURE9 GetEFBDepthTexture(const EFBRectangle& sourceRc);
|
static LPDIRECT3DTEXTURE9 GetEFBDepthTexture(const EFBRectangle& sourceRc);
|
||||||
|
|
||||||
static LPDIRECT3DSURFACE9 GetEFBColorRTSurface();
|
static LPDIRECT3DSURFACE9 GetEFBColorRTSurface();
|
||||||
static LPDIRECT3DSURFACE9 GetEFBDepthRTSurface();
|
static LPDIRECT3DSURFACE9 GetEFBDepthRTSurface();
|
||||||
static LPDIRECT3DSURFACE9 GetEFBColorOffScreenRTSurface();
|
static LPDIRECT3DSURFACE9 GetEFBColorOffScreenRTSurface();
|
||||||
static LPDIRECT3DSURFACE9 GetEFBDepthOffScreenRTSurface();
|
static LPDIRECT3DSURFACE9 GetEFBDepthOffScreenRTSurface();
|
||||||
static D3DFORMAT GetEFBDepthRTSurfaceFormat();
|
static D3DFORMAT GetEFBDepthRTSurfaceFormat();
|
||||||
static D3DFORMAT GetEFBColorRTSurfaceFormat();
|
static D3DFORMAT GetEFBColorRTSurfaceFormat();
|
||||||
static D3DFORMAT GetEFBDepthReadSurfaceFormat();
|
static D3DFORMAT GetEFBDepthReadSurfaceFormat();
|
||||||
static LPDIRECT3DSURFACE9 GetEFBColorReadSurface();
|
static LPDIRECT3DSURFACE9 GetEFBColorReadSurface();
|
||||||
static LPDIRECT3DSURFACE9 GetEFBDepthReadSurface();
|
static LPDIRECT3DSURFACE9 GetEFBDepthReadSurface();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void copyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc);
|
void copyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc);
|
||||||
void copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc);
|
void copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc);
|
||||||
const XFBSource** getRealXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount);
|
const XFBSource** getRealXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount);
|
||||||
|
|
||||||
static XFBSource m_realXFBSource; // Only used in Real XFB mode
|
static XFBSource m_realXFBSource; // Only used in Real XFB mode
|
||||||
|
|
||||||
const XFBSource* m_overlappingXFBArray[MAX_VIRTUAL_XFB];
|
const XFBSource* m_overlappingXFBArray[MAX_VIRTUAL_XFB];
|
||||||
|
|
||||||
static LPDIRECT3DTEXTURE9 s_efb_color_texture;//Texture thats contains the color data of the render target
|
static LPDIRECT3DTEXTURE9 s_efb_color_texture;//Texture thats contains the color data of the render target
|
||||||
static LPDIRECT3DTEXTURE9 s_efb_colorRead_texture;//1 pixel texture for temporal data store
|
static LPDIRECT3DTEXTURE9 s_efb_colorRead_texture;//1 pixel texture for temporal data store
|
||||||
static LPDIRECT3DTEXTURE9 s_efb_depth_texture;//Texture thats contains the depth data of the render target
|
static LPDIRECT3DTEXTURE9 s_efb_depth_texture;//Texture thats contains the depth data of the render target
|
||||||
static LPDIRECT3DTEXTURE9 s_efb_depthRead_texture;//4 pixel texture for temporal data store
|
static LPDIRECT3DTEXTURE9 s_efb_depthRead_texture;//4 pixel texture for temporal data store
|
||||||
|
|
||||||
static LPDIRECT3DSURFACE9 s_efb_depth_surface;//Depth Surface
|
static LPDIRECT3DSURFACE9 s_efb_depth_surface;//Depth Surface
|
||||||
static LPDIRECT3DSURFACE9 s_efb_color_surface;//Color Surface
|
static LPDIRECT3DSURFACE9 s_efb_color_surface;//Color Surface
|
||||||
static LPDIRECT3DSURFACE9 s_efb_color_ReadBuffer;//Surface 0 of s_efb_colorRead_texture
|
static LPDIRECT3DSURFACE9 s_efb_color_ReadBuffer;//Surface 0 of s_efb_colorRead_texture
|
||||||
static LPDIRECT3DSURFACE9 s_efb_depth_ReadBuffer;//Surface 0 of s_efb_depthRead_texture
|
static LPDIRECT3DSURFACE9 s_efb_depth_ReadBuffer;//Surface 0 of s_efb_depthRead_texture
|
||||||
static LPDIRECT3DSURFACE9 s_efb_color_OffScreenReadBuffer;//System memory Surface that can be locked to retriebe the data
|
static LPDIRECT3DSURFACE9 s_efb_color_OffScreenReadBuffer;//System memory Surface that can be locked to retriebe the data
|
||||||
static LPDIRECT3DSURFACE9 s_efb_depth_OffScreenReadBuffer;//System memory Surface that can be locked to retriebe the data
|
static LPDIRECT3DSURFACE9 s_efb_depth_OffScreenReadBuffer;//System memory Surface that can be locked to retriebe the data
|
||||||
|
|
||||||
static D3DFORMAT s_efb_color_surface_Format;//Format of the color Surface
|
static D3DFORMAT s_efb_color_surface_Format;//Format of the color Surface
|
||||||
static D3DFORMAT s_efb_depth_surface_Format;//Format of the Depth Surface
|
static D3DFORMAT s_efb_depth_surface_Format;//Format of the Depth Surface
|
||||||
static D3DFORMAT s_efb_depth_ReadBuffer_Format;//Format of the Depth color Read Surface
|
static D3DFORMAT s_efb_depth_ReadBuffer_Format;//Format of the Depth color Read Surface
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,178 +1,178 @@
|
|||||||
|
|
||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
#include "DX9_D3DBase.h"
|
#include "DX9_D3DBase.h"
|
||||||
|
|
||||||
#include "Profiler.h"
|
#include "Profiler.h"
|
||||||
#include "x64Emitter.h"
|
#include "x64Emitter.h"
|
||||||
#include "ABI.h"
|
#include "ABI.h"
|
||||||
#include "MemoryUtil.h"
|
#include "MemoryUtil.h"
|
||||||
#include "VertexShaderGen.h"
|
#include "VertexShaderGen.h"
|
||||||
|
|
||||||
#include "CPMemory.h"
|
#include "CPMemory.h"
|
||||||
|
|
||||||
#include "DX9_VertexManager.h"
|
#include "DX9_VertexManager.h"
|
||||||
|
|
||||||
namespace DX9
|
namespace DX9
|
||||||
{
|
{
|
||||||
|
|
||||||
class D3DVertexFormat : public NativeVertexFormat
|
class D3DVertexFormat : public NativeVertexFormat
|
||||||
{
|
{
|
||||||
LPDIRECT3DVERTEXDECLARATION9 d3d_decl;
|
LPDIRECT3DVERTEXDECLARATION9 d3d_decl;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
D3DVertexFormat();
|
D3DVertexFormat();
|
||||||
~D3DVertexFormat();
|
~D3DVertexFormat();
|
||||||
virtual void Initialize(const PortableVertexDeclaration &_vtx_decl);
|
virtual void Initialize(const PortableVertexDeclaration &_vtx_decl);
|
||||||
virtual void SetupVertexPointers() const;
|
virtual void SetupVertexPointers() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
NativeVertexFormat *VertexManager::CreateNativeVertexFormat()
|
NativeVertexFormat *VertexManager::CreateNativeVertexFormat()
|
||||||
{
|
{
|
||||||
return new D3DVertexFormat();
|
return new D3DVertexFormat();
|
||||||
}
|
}
|
||||||
|
|
||||||
D3DVertexFormat::D3DVertexFormat() : d3d_decl(NULL)
|
D3DVertexFormat::D3DVertexFormat() : d3d_decl(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
D3DVertexFormat::~D3DVertexFormat()
|
D3DVertexFormat::~D3DVertexFormat()
|
||||||
{
|
{
|
||||||
if (d3d_decl)
|
if (d3d_decl)
|
||||||
{
|
{
|
||||||
d3d_decl->Release();
|
d3d_decl->Release();
|
||||||
d3d_decl = NULL;
|
d3d_decl = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
D3DDECLTYPE VarToD3D(VarType t, int size)
|
D3DDECLTYPE VarToD3D(VarType t, int size)
|
||||||
{
|
{
|
||||||
if (t < 0 || t > 4) {
|
if (t < 0 || t > 4) {
|
||||||
PanicAlert("VarToD3D: Invalid VarType %i", t);
|
PanicAlert("VarToD3D: Invalid VarType %i", t);
|
||||||
}
|
}
|
||||||
static const D3DDECLTYPE lookup1[5] = {
|
static const D3DDECLTYPE lookup1[5] = {
|
||||||
D3DDECLTYPE_UNUSED, D3DDECLTYPE_UNUSED, D3DDECLTYPE_UNUSED, D3DDECLTYPE_UNUSED, D3DDECLTYPE_FLOAT1,
|
D3DDECLTYPE_UNUSED, D3DDECLTYPE_UNUSED, D3DDECLTYPE_UNUSED, D3DDECLTYPE_UNUSED, D3DDECLTYPE_FLOAT1,
|
||||||
};
|
};
|
||||||
static const D3DDECLTYPE lookup2[5] = {
|
static const D3DDECLTYPE lookup2[5] = {
|
||||||
D3DDECLTYPE_UNUSED, D3DDECLTYPE_UNUSED, D3DDECLTYPE_SHORT2N, D3DDECLTYPE_USHORT2N, D3DDECLTYPE_FLOAT2,
|
D3DDECLTYPE_UNUSED, D3DDECLTYPE_UNUSED, D3DDECLTYPE_SHORT2N, D3DDECLTYPE_USHORT2N, D3DDECLTYPE_FLOAT2,
|
||||||
};
|
};
|
||||||
static const D3DDECLTYPE lookup3[5] = {
|
static const D3DDECLTYPE lookup3[5] = {
|
||||||
D3DDECLTYPE_UNUSED, D3DDECLTYPE_UNUSED, D3DDECLTYPE_UNUSED, D3DDECLTYPE_UNUSED, D3DDECLTYPE_FLOAT3,
|
D3DDECLTYPE_UNUSED, D3DDECLTYPE_UNUSED, D3DDECLTYPE_UNUSED, D3DDECLTYPE_UNUSED, D3DDECLTYPE_FLOAT3,
|
||||||
};
|
};
|
||||||
// Sadly, D3D9 has no SBYTE4N. D3D10 does, though.
|
// Sadly, D3D9 has no SBYTE4N. D3D10 does, though.
|
||||||
static const D3DDECLTYPE lookup4[5] = {
|
static const D3DDECLTYPE lookup4[5] = {
|
||||||
D3DDECLTYPE_UNUSED, D3DDECLTYPE_UBYTE4N, D3DDECLTYPE_SHORT4N, D3DDECLTYPE_USHORT4N, D3DDECLTYPE_FLOAT4,
|
D3DDECLTYPE_UNUSED, D3DDECLTYPE_UBYTE4N, D3DDECLTYPE_SHORT4N, D3DDECLTYPE_USHORT4N, D3DDECLTYPE_FLOAT4,
|
||||||
};
|
};
|
||||||
D3DDECLTYPE retval = D3DDECLTYPE_UNUSED;
|
D3DDECLTYPE retval = D3DDECLTYPE_UNUSED;
|
||||||
switch (size) {
|
switch (size) {
|
||||||
case 1: retval = lookup1[t]; break;
|
case 1: retval = lookup1[t]; break;
|
||||||
case 2: retval = lookup2[t]; break;
|
case 2: retval = lookup2[t]; break;
|
||||||
case 3: retval = lookup3[t]; break;
|
case 3: retval = lookup3[t]; break;
|
||||||
case 4: retval = lookup4[t]; break;
|
case 4: retval = lookup4[t]; break;
|
||||||
default: PanicAlert("VarToD3D: size wrong (%i)", size); break;
|
default: PanicAlert("VarToD3D: size wrong (%i)", size); break;
|
||||||
}
|
}
|
||||||
if (retval == D3DDECLTYPE_UNUSED) {
|
if (retval == D3DDECLTYPE_UNUSED) {
|
||||||
PanicAlert("VarToD3D: Invalid type/size combo %i , %i", (int)t, size);
|
PanicAlert("VarToD3D: Invalid type/size combo %i , %i", (int)t, size);
|
||||||
}
|
}
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3DVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl)
|
void D3DVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl)
|
||||||
{
|
{
|
||||||
vertex_stride = _vtx_decl.stride;
|
vertex_stride = _vtx_decl.stride;
|
||||||
|
|
||||||
D3DVERTEXELEMENT9 *elems = new D3DVERTEXELEMENT9[32];
|
D3DVERTEXELEMENT9 *elems = new D3DVERTEXELEMENT9[32];
|
||||||
memset(elems, 0, sizeof(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.
|
// 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.
|
// Same for method.
|
||||||
|
|
||||||
// So, here we go. First position:
|
// So, here we go. First position:
|
||||||
int elem_idx = 0;
|
int elem_idx = 0;
|
||||||
elems[elem_idx].Offset = 0; // Positions are always first, at position 0. Always float3.
|
elems[elem_idx].Offset = 0; // Positions are always first, at position 0. Always float3.
|
||||||
elems[elem_idx].Type = D3DDECLTYPE_FLOAT3;
|
elems[elem_idx].Type = D3DDECLTYPE_FLOAT3;
|
||||||
elems[elem_idx].Usage = D3DDECLUSAGE_POSITION;
|
elems[elem_idx].Usage = D3DDECLUSAGE_POSITION;
|
||||||
++elem_idx;
|
++elem_idx;
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
if (_vtx_decl.normal_offset[i] > 0)
|
if (_vtx_decl.normal_offset[i] > 0)
|
||||||
{
|
{
|
||||||
elems[elem_idx].Offset = _vtx_decl.normal_offset[i];
|
elems[elem_idx].Offset = _vtx_decl.normal_offset[i];
|
||||||
elems[elem_idx].Type = VarToD3D(_vtx_decl.normal_gl_type, _vtx_decl.normal_gl_size);
|
elems[elem_idx].Type = VarToD3D(_vtx_decl.normal_gl_type, _vtx_decl.normal_gl_size);
|
||||||
elems[elem_idx].Usage = D3DDECLUSAGE_NORMAL;
|
elems[elem_idx].Usage = D3DDECLUSAGE_NORMAL;
|
||||||
elems[elem_idx].UsageIndex = i;
|
elems[elem_idx].UsageIndex = i;
|
||||||
++elem_idx;
|
++elem_idx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++)
|
for (int i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
if (_vtx_decl.color_offset[i] > 0)
|
if (_vtx_decl.color_offset[i] > 0)
|
||||||
{
|
{
|
||||||
elems[elem_idx].Offset = _vtx_decl.color_offset[i];
|
elems[elem_idx].Offset = _vtx_decl.color_offset[i];
|
||||||
elems[elem_idx].Type = VarToD3D(_vtx_decl.color_gl_type, 4);
|
elems[elem_idx].Type = VarToD3D(_vtx_decl.color_gl_type, 4);
|
||||||
elems[elem_idx].Usage = D3DDECLUSAGE_COLOR;
|
elems[elem_idx].Usage = D3DDECLUSAGE_COLOR;
|
||||||
elems[elem_idx].UsageIndex = i;
|
elems[elem_idx].UsageIndex = i;
|
||||||
++elem_idx;
|
++elem_idx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
if (_vtx_decl.texcoord_offset[i] > 0)
|
if (_vtx_decl.texcoord_offset[i] > 0)
|
||||||
{
|
{
|
||||||
elems[elem_idx].Offset = _vtx_decl.texcoord_offset[i];
|
elems[elem_idx].Offset = _vtx_decl.texcoord_offset[i];
|
||||||
elems[elem_idx].Type = VarToD3D(_vtx_decl.texcoord_gl_type[i], _vtx_decl.texcoord_size[i]);
|
elems[elem_idx].Type = VarToD3D(_vtx_decl.texcoord_gl_type[i], _vtx_decl.texcoord_size[i]);
|
||||||
elems[elem_idx].Usage = D3DDECLUSAGE_TEXCOORD;
|
elems[elem_idx].Usage = D3DDECLUSAGE_TEXCOORD;
|
||||||
elems[elem_idx].UsageIndex = i;
|
elems[elem_idx].UsageIndex = i;
|
||||||
++elem_idx;
|
++elem_idx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_vtx_decl.posmtx_offset != -1)
|
if (_vtx_decl.posmtx_offset != -1)
|
||||||
{
|
{
|
||||||
elems[elem_idx].Offset = _vtx_decl.posmtx_offset;
|
elems[elem_idx].Offset = _vtx_decl.posmtx_offset;
|
||||||
elems[elem_idx].Usage = D3DDECLUSAGE_BLENDINDICES;
|
elems[elem_idx].Usage = D3DDECLUSAGE_BLENDINDICES;
|
||||||
elems[elem_idx].Type = D3DDECLTYPE_D3DCOLOR;
|
elems[elem_idx].Type = D3DDECLTYPE_D3DCOLOR;
|
||||||
elems[elem_idx].UsageIndex = 0;
|
elems[elem_idx].UsageIndex = 0;
|
||||||
++elem_idx;
|
++elem_idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
// End marker
|
// End marker
|
||||||
elems[elem_idx].Stream = 0xff;
|
elems[elem_idx].Stream = 0xff;
|
||||||
elems[elem_idx].Type = D3DDECLTYPE_UNUSED;
|
elems[elem_idx].Type = D3DDECLTYPE_UNUSED;
|
||||||
++elem_idx;
|
++elem_idx;
|
||||||
|
|
||||||
if (FAILED(D3D::dev->CreateVertexDeclaration(elems, &d3d_decl)))
|
if (FAILED(D3D::dev->CreateVertexDeclaration(elems, &d3d_decl)))
|
||||||
{
|
{
|
||||||
PanicAlert("Failed to create D3D vertex declaration!");
|
PanicAlert("Failed to create D3D vertex declaration!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
delete [] elems;
|
delete [] elems;
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3DVertexFormat::SetupVertexPointers() const
|
void D3DVertexFormat::SetupVertexPointers() const
|
||||||
{
|
{
|
||||||
if (d3d_decl)
|
if (d3d_decl)
|
||||||
D3D::SetVertexDeclaration(d3d_decl);
|
D3D::SetVertexDeclaration(d3d_decl);
|
||||||
else
|
else
|
||||||
ERROR_LOG(VIDEO, "invalid d3d decl");
|
ERROR_LOG(VIDEO, "invalid d3d decl");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,392 +1,392 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "Hash.h"
|
#include "Hash.h"
|
||||||
#include "FileUtil.h"
|
#include "FileUtil.h"
|
||||||
#include "LinearDiskCache.h"
|
#include "LinearDiskCache.h"
|
||||||
|
|
||||||
#include "DX9_D3DBase.h"
|
#include "DX9_D3DBase.h"
|
||||||
#include "DX9_D3DShader.h"
|
#include "DX9_D3DShader.h"
|
||||||
#include "Statistics.h"
|
#include "Statistics.h"
|
||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
#include "PixelShaderGen.h"
|
#include "PixelShaderGen.h"
|
||||||
#include "PixelShaderManager.h"
|
#include "PixelShaderManager.h"
|
||||||
#include "DX9_PixelShaderCache.h"
|
#include "DX9_PixelShaderCache.h"
|
||||||
#include "VertexLoader.h"
|
#include "VertexLoader.h"
|
||||||
#include "BPMemory.h"
|
#include "BPMemory.h"
|
||||||
#include "XFMemory.h"
|
#include "XFMemory.h"
|
||||||
#include "ImageWrite.h"
|
#include "ImageWrite.h"
|
||||||
|
|
||||||
#include "../Main.h"
|
#include "../Main.h"
|
||||||
|
|
||||||
//#include "Debugger/Debugger.h"
|
//#include "Debugger/Debugger.h"
|
||||||
|
|
||||||
namespace DX9
|
namespace DX9
|
||||||
{
|
{
|
||||||
|
|
||||||
PixelShaderCache::PSCache PixelShaderCache::PixelShaders;
|
PixelShaderCache::PSCache PixelShaderCache::PixelShaders;
|
||||||
const PixelShaderCache::PSCacheEntry *PixelShaderCache::last_entry;
|
const PixelShaderCache::PSCacheEntry *PixelShaderCache::last_entry;
|
||||||
|
|
||||||
static LinearDiskCache g_ps_disk_cache;
|
static LinearDiskCache g_ps_disk_cache;
|
||||||
static std::set<u32> unique_shaders;
|
static std::set<u32> unique_shaders;
|
||||||
|
|
||||||
#define MAX_SSAA_SHADERS 3
|
#define MAX_SSAA_SHADERS 3
|
||||||
|
|
||||||
static LPDIRECT3DPIXELSHADER9 s_ColorMatrixProgram[MAX_SSAA_SHADERS];
|
static LPDIRECT3DPIXELSHADER9 s_ColorMatrixProgram[MAX_SSAA_SHADERS];
|
||||||
static LPDIRECT3DPIXELSHADER9 s_ColorCopyProgram[MAX_SSAA_SHADERS];
|
static LPDIRECT3DPIXELSHADER9 s_ColorCopyProgram[MAX_SSAA_SHADERS];
|
||||||
static LPDIRECT3DPIXELSHADER9 s_DepthMatrixProgram[MAX_SSAA_SHADERS];
|
static LPDIRECT3DPIXELSHADER9 s_DepthMatrixProgram[MAX_SSAA_SHADERS];
|
||||||
static LPDIRECT3DPIXELSHADER9 s_ClearProgram = 0;
|
static LPDIRECT3DPIXELSHADER9 s_ClearProgram = 0;
|
||||||
|
|
||||||
LPDIRECT3DPIXELSHADER9 PixelShaderCache::GetColorMatrixProgram(int SSAAMode)
|
LPDIRECT3DPIXELSHADER9 PixelShaderCache::GetColorMatrixProgram(int SSAAMode)
|
||||||
{
|
{
|
||||||
return s_ColorMatrixProgram[SSAAMode % MAX_SSAA_SHADERS];
|
return s_ColorMatrixProgram[SSAAMode % MAX_SSAA_SHADERS];
|
||||||
}
|
}
|
||||||
|
|
||||||
LPDIRECT3DPIXELSHADER9 PixelShaderCache::GetDepthMatrixProgram(int SSAAMode)
|
LPDIRECT3DPIXELSHADER9 PixelShaderCache::GetDepthMatrixProgram(int SSAAMode)
|
||||||
{
|
{
|
||||||
return s_DepthMatrixProgram[SSAAMode % MAX_SSAA_SHADERS];
|
return s_DepthMatrixProgram[SSAAMode % MAX_SSAA_SHADERS];
|
||||||
}
|
}
|
||||||
|
|
||||||
LPDIRECT3DPIXELSHADER9 PixelShaderCache::GetColorCopyProgram(int SSAAMode)
|
LPDIRECT3DPIXELSHADER9 PixelShaderCache::GetColorCopyProgram(int SSAAMode)
|
||||||
{
|
{
|
||||||
return s_ColorCopyProgram[SSAAMode % MAX_SSAA_SHADERS];
|
return s_ColorCopyProgram[SSAAMode % MAX_SSAA_SHADERS];
|
||||||
}
|
}
|
||||||
|
|
||||||
LPDIRECT3DPIXELSHADER9 PixelShaderCache::GetClearProgram()
|
LPDIRECT3DPIXELSHADER9 PixelShaderCache::GetClearProgram()
|
||||||
{
|
{
|
||||||
return s_ClearProgram;
|
return s_ClearProgram;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PixelShaderCache::SetPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4)
|
void PixelShaderCache::SetPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4)
|
||||||
{
|
{
|
||||||
float f[4] = { f1, f2, f3, f4 };
|
float f[4] = { f1, f2, f3, f4 };
|
||||||
D3D::dev->SetPixelShaderConstantF(const_number, f, 1);
|
D3D::dev->SetPixelShaderConstantF(const_number, f, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PixelShaderCache::SetPSConstant4fv(unsigned int const_number, const float *f)
|
void PixelShaderCache::SetPSConstant4fv(unsigned int const_number, const float *f)
|
||||||
{
|
{
|
||||||
D3D::dev->SetPixelShaderConstantF(const_number, f, 1);
|
D3D::dev->SetPixelShaderConstantF(const_number, f, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PixelShaderCache::SetMultiPSConstant4fv(unsigned int const_number, unsigned int count, const float *f)
|
void PixelShaderCache::SetMultiPSConstant4fv(unsigned int const_number, unsigned int count, const float *f)
|
||||||
{
|
{
|
||||||
D3D::dev->SetPixelShaderConstantF(const_number, f, count);
|
D3D::dev->SetPixelShaderConstantF(const_number, f, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
class PixelShaderCacheInserter : public LinearDiskCacheReader {
|
class PixelShaderCacheInserter : public LinearDiskCacheReader {
|
||||||
public:
|
public:
|
||||||
void Read(const u8 *key, int key_size, const u8 *value, int value_size)
|
void Read(const u8 *key, int key_size, const u8 *value, int value_size)
|
||||||
{
|
{
|
||||||
PIXELSHADERUID uid;
|
PIXELSHADERUID uid;
|
||||||
if (key_size != sizeof(uid)) {
|
if (key_size != sizeof(uid)) {
|
||||||
ERROR_LOG(VIDEO, "Wrong key size in pixel shader cache");
|
ERROR_LOG(VIDEO, "Wrong key size in pixel shader cache");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memcpy(&uid, key, key_size);
|
memcpy(&uid, key, key_size);
|
||||||
PixelShaderCache::InsertByteCode(uid, value, value_size, false);
|
PixelShaderCache::InsertByteCode(uid, value, value_size, false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
PixelShaderCache::PixelShaderCache()
|
PixelShaderCache::PixelShaderCache()
|
||||||
{
|
{
|
||||||
//program used for clear screen
|
//program used for clear screen
|
||||||
char pprog[3072];
|
char pprog[3072];
|
||||||
sprintf(pprog, "void main(\n"
|
sprintf(pprog, "void main(\n"
|
||||||
"out float4 ocol0 : COLOR0,\n"
|
"out float4 ocol0 : COLOR0,\n"
|
||||||
" in float4 incol0 : COLOR0){\n"
|
" in float4 incol0 : COLOR0){\n"
|
||||||
"ocol0 = incol0;\n"
|
"ocol0 = incol0;\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
s_ClearProgram = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog));
|
s_ClearProgram = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog));
|
||||||
|
|
||||||
//Used for Copy/resolve the color buffer
|
//Used for Copy/resolve the color buffer
|
||||||
//1 Sample
|
//1 Sample
|
||||||
sprintf(pprog, "uniform sampler samp0 : register(s0);\n"
|
sprintf(pprog, "uniform sampler samp0 : register(s0);\n"
|
||||||
"void main(\n"
|
"void main(\n"
|
||||||
"out float4 ocol0 : COLOR0,\n"
|
"out float4 ocol0 : COLOR0,\n"
|
||||||
"in float2 uv0 : TEXCOORD0){\n"
|
"in float2 uv0 : TEXCOORD0){\n"
|
||||||
"ocol0 = tex2D(samp0,uv0);\n"
|
"ocol0 = tex2D(samp0,uv0);\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
s_ColorCopyProgram[0] = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog));
|
s_ColorCopyProgram[0] = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog));
|
||||||
|
|
||||||
//1 Samples SSAA
|
//1 Samples SSAA
|
||||||
sprintf(pprog, "uniform sampler samp0 : register(s0);\n"
|
sprintf(pprog, "uniform sampler samp0 : register(s0);\n"
|
||||||
"void main(\n"
|
"void main(\n"
|
||||||
"out float4 ocol0 : COLOR0,\n"
|
"out float4 ocol0 : COLOR0,\n"
|
||||||
"in float4 uv0 : TEXCOORD0,\n"
|
"in float4 uv0 : TEXCOORD0,\n"
|
||||||
"in float4 uv1 : TEXCOORD1){\n"
|
"in float4 uv1 : TEXCOORD1){\n"
|
||||||
"ocol0 = tex2D(samp0,uv0.xy);\n"
|
"ocol0 = tex2D(samp0,uv0.xy);\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
s_ColorCopyProgram[1] = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog));
|
s_ColorCopyProgram[1] = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog));
|
||||||
|
|
||||||
//4 Samples SSAA
|
//4 Samples SSAA
|
||||||
sprintf(pprog, "uniform sampler samp0 : register(s0);\n"
|
sprintf(pprog, "uniform sampler samp0 : register(s0);\n"
|
||||||
"void main(\n"
|
"void main(\n"
|
||||||
"out float4 ocol0 : COLOR0,\n"
|
"out float4 ocol0 : COLOR0,\n"
|
||||||
"in float4 uv0 : TEXCOORD0,\n"
|
"in float4 uv0 : TEXCOORD0,\n"
|
||||||
"in float4 uv1 : TEXCOORD1,\n"
|
"in float4 uv1 : TEXCOORD1,\n"
|
||||||
"in float4 uv2 : TEXCOORD2,\n"
|
"in float4 uv2 : TEXCOORD2,\n"
|
||||||
"in float4 uv3 : TEXCOORD3){\n"
|
"in float4 uv3 : TEXCOORD3){\n"
|
||||||
"ocol0 = (tex2D(samp0,uv1.xy) + tex2D(samp0,uv1.wz) + tex2D(samp0,uv2.xy) + tex2D(samp0,uv2.wz))*0.25;\n"
|
"ocol0 = (tex2D(samp0,uv1.xy) + tex2D(samp0,uv1.wz) + tex2D(samp0,uv2.xy) + tex2D(samp0,uv2.wz))*0.25;\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
s_ColorCopyProgram[2] = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog));
|
s_ColorCopyProgram[2] = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Color conversion Programs
|
//Color conversion Programs
|
||||||
//1 sample
|
//1 sample
|
||||||
sprintf(pprog, "uniform sampler samp0 : register(s0);\n"
|
sprintf(pprog, "uniform sampler samp0 : register(s0);\n"
|
||||||
"uniform float4 cColMatrix[5] : register(c%d);\n"
|
"uniform float4 cColMatrix[5] : register(c%d);\n"
|
||||||
"void main(\n"
|
"void main(\n"
|
||||||
"out float4 ocol0 : COLOR0,\n"
|
"out float4 ocol0 : COLOR0,\n"
|
||||||
" in float2 uv0 : TEXCOORD0){\n"
|
" in float2 uv0 : TEXCOORD0){\n"
|
||||||
"float4 texcol = tex2D(samp0,uv0);\n"
|
"float4 texcol = tex2D(samp0,uv0);\n"
|
||||||
"ocol0 = float4(dot(texcol,cColMatrix[0]),dot(texcol,cColMatrix[1]),dot(texcol,cColMatrix[2]),dot(texcol,cColMatrix[3])) + cColMatrix[4];\n"
|
"ocol0 = float4(dot(texcol,cColMatrix[0]),dot(texcol,cColMatrix[1]),dot(texcol,cColMatrix[2]),dot(texcol,cColMatrix[3])) + cColMatrix[4];\n"
|
||||||
"}\n",C_COLORMATRIX);
|
"}\n",C_COLORMATRIX);
|
||||||
s_ColorMatrixProgram[0] = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog));
|
s_ColorMatrixProgram[0] = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog));
|
||||||
|
|
||||||
//1 samples SSAA
|
//1 samples SSAA
|
||||||
sprintf(pprog, "uniform sampler samp0 : register(s0);\n"
|
sprintf(pprog, "uniform sampler samp0 : register(s0);\n"
|
||||||
"uniform float4 cColMatrix[5] : register(c%d);\n"
|
"uniform float4 cColMatrix[5] : register(c%d);\n"
|
||||||
"void main(\n"
|
"void main(\n"
|
||||||
"out float4 ocol0 : COLOR0,\n"
|
"out float4 ocol0 : COLOR0,\n"
|
||||||
"in float4 uv0 : TEXCOORD0,\n"
|
"in float4 uv0 : TEXCOORD0,\n"
|
||||||
"in float4 uv1 : TEXCOORD1){\n"
|
"in float4 uv1 : TEXCOORD1){\n"
|
||||||
"float4 texcol = tex2D(samp0,uv0.xy);\n"
|
"float4 texcol = tex2D(samp0,uv0.xy);\n"
|
||||||
"ocol0 = float4(dot(texcol,cColMatrix[0]),dot(texcol,cColMatrix[1]),dot(texcol,cColMatrix[2]),dot(texcol,cColMatrix[3])) + cColMatrix[4];\n"
|
"ocol0 = float4(dot(texcol,cColMatrix[0]),dot(texcol,cColMatrix[1]),dot(texcol,cColMatrix[2]),dot(texcol,cColMatrix[3])) + cColMatrix[4];\n"
|
||||||
"}\n",C_COLORMATRIX);
|
"}\n",C_COLORMATRIX);
|
||||||
s_ColorMatrixProgram[1] = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog));
|
s_ColorMatrixProgram[1] = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog));
|
||||||
|
|
||||||
//4 samples SSAA
|
//4 samples SSAA
|
||||||
sprintf(pprog, "uniform sampler samp0 : register(s0);\n"
|
sprintf(pprog, "uniform sampler samp0 : register(s0);\n"
|
||||||
"uniform float4 cColMatrix[5] : register(c%d);\n"
|
"uniform float4 cColMatrix[5] : register(c%d);\n"
|
||||||
"void main(\n"
|
"void main(\n"
|
||||||
"out float4 ocol0 : COLOR0,\n"
|
"out float4 ocol0 : COLOR0,\n"
|
||||||
"in float4 uv0 : TEXCOORD0,\n"
|
"in float4 uv0 : TEXCOORD0,\n"
|
||||||
"in float4 uv1 : TEXCOORD1,\n"
|
"in float4 uv1 : TEXCOORD1,\n"
|
||||||
"in float4 uv2 : TEXCOORD2,\n"
|
"in float4 uv2 : TEXCOORD2,\n"
|
||||||
"in float4 uv3 : TEXCOORD3){\n"
|
"in float4 uv3 : TEXCOORD3){\n"
|
||||||
"float4 texcol = (tex2D(samp0,uv1.xy) + tex2D(samp0,uv1.wz) + tex2D(samp0,uv2.xy) + tex2D(samp0,uv2.wz))*0.25f;\n"
|
"float4 texcol = (tex2D(samp0,uv1.xy) + tex2D(samp0,uv1.wz) + tex2D(samp0,uv2.xy) + tex2D(samp0,uv2.wz))*0.25f;\n"
|
||||||
"ocol0 = float4(dot(texcol,cColMatrix[0]),dot(texcol,cColMatrix[1]),dot(texcol,cColMatrix[2]),dot(texcol,cColMatrix[3])) + cColMatrix[4];\n"
|
"ocol0 = float4(dot(texcol,cColMatrix[0]),dot(texcol,cColMatrix[1]),dot(texcol,cColMatrix[2]),dot(texcol,cColMatrix[3])) + cColMatrix[4];\n"
|
||||||
"}\n",C_COLORMATRIX);
|
"}\n",C_COLORMATRIX);
|
||||||
s_ColorMatrixProgram[2] = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog));
|
s_ColorMatrixProgram[2] = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog));
|
||||||
|
|
||||||
//Depth copy programs
|
//Depth copy programs
|
||||||
//1 sample
|
//1 sample
|
||||||
sprintf(pprog, "uniform sampler samp0 : register(s0);\n"
|
sprintf(pprog, "uniform sampler samp0 : register(s0);\n"
|
||||||
"uniform float4 cColMatrix[5] : register(c%d);\n"
|
"uniform float4 cColMatrix[5] : register(c%d);\n"
|
||||||
"void main(\n"
|
"void main(\n"
|
||||||
"out float4 ocol0 : COLOR0,\n"
|
"out float4 ocol0 : COLOR0,\n"
|
||||||
" in float2 uv0 : TEXCOORD0){\n"
|
" in float2 uv0 : TEXCOORD0){\n"
|
||||||
"float4 texcol = tex2D(samp0,uv0);\n"
|
"float4 texcol = tex2D(samp0,uv0);\n"
|
||||||
"float4 EncodedDepth = frac((texcol.r * (16777215.0f/16777216.0f)) * float4(1.0f,255.0f,255.0f*255.0f,255.0f*255.0f*255.0f));\n"
|
"float4 EncodedDepth = frac((texcol.r * (16777215.0f/16777216.0f)) * float4(1.0f,255.0f,255.0f*255.0f,255.0f*255.0f*255.0f));\n"
|
||||||
"texcol = float4((EncodedDepth.rgb * (16777216.0f/16777215.0f)),1.0f);\n"
|
"texcol = float4((EncodedDepth.rgb * (16777216.0f/16777215.0f)),1.0f);\n"
|
||||||
"ocol0 = float4(dot(texcol,cColMatrix[0]),dot(texcol,cColMatrix[1]),dot(texcol,cColMatrix[2]),dot(texcol,cColMatrix[3])) + cColMatrix[4];\n"
|
"ocol0 = float4(dot(texcol,cColMatrix[0]),dot(texcol,cColMatrix[1]),dot(texcol,cColMatrix[2]),dot(texcol,cColMatrix[3])) + cColMatrix[4];\n"
|
||||||
"}\n",C_COLORMATRIX);
|
"}\n",C_COLORMATRIX);
|
||||||
s_DepthMatrixProgram[0] = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog));
|
s_DepthMatrixProgram[0] = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog));
|
||||||
|
|
||||||
//1 sample SSAA
|
//1 sample SSAA
|
||||||
sprintf(pprog, "uniform sampler samp0 : register(s0);\n"
|
sprintf(pprog, "uniform sampler samp0 : register(s0);\n"
|
||||||
"uniform float4 cColMatrix[5] : register(c%d);\n"
|
"uniform float4 cColMatrix[5] : register(c%d);\n"
|
||||||
"void main(\n"
|
"void main(\n"
|
||||||
"out float4 ocol0 : COLOR0,\n"
|
"out float4 ocol0 : COLOR0,\n"
|
||||||
"in float4 uv0 : TEXCOORD0,\n"
|
"in float4 uv0 : TEXCOORD0,\n"
|
||||||
"in float4 uv1 : TEXCOORD1){\n"
|
"in float4 uv1 : TEXCOORD1){\n"
|
||||||
"float4 texcol = tex2D(samp0,uv0.xy);\n"
|
"float4 texcol = tex2D(samp0,uv0.xy);\n"
|
||||||
"float4 EncodedDepth = frac((texcol.r * (16777215.0f/16777216.0f)) * float4(1.0f,255.0f,255.0f*255.0f,255.0f*255.0f*255.0f));\n"
|
"float4 EncodedDepth = frac((texcol.r * (16777215.0f/16777216.0f)) * float4(1.0f,255.0f,255.0f*255.0f,255.0f*255.0f*255.0f));\n"
|
||||||
"texcol = float4((EncodedDepth.rgb * (16777216.0f/16777215.0f)),1.0f);\n"
|
"texcol = float4((EncodedDepth.rgb * (16777216.0f/16777215.0f)),1.0f);\n"
|
||||||
"ocol0 = float4(dot(texcol,cColMatrix[0]),dot(texcol,cColMatrix[1]),dot(texcol,cColMatrix[2]),dot(texcol,cColMatrix[3])) + cColMatrix[4];\n"
|
"ocol0 = float4(dot(texcol,cColMatrix[0]),dot(texcol,cColMatrix[1]),dot(texcol,cColMatrix[2]),dot(texcol,cColMatrix[3])) + cColMatrix[4];\n"
|
||||||
"}\n",C_COLORMATRIX);
|
"}\n",C_COLORMATRIX);
|
||||||
s_DepthMatrixProgram[1] = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog));
|
s_DepthMatrixProgram[1] = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog));
|
||||||
|
|
||||||
//4 sample SSAA
|
//4 sample SSAA
|
||||||
sprintf(pprog, "uniform sampler samp0 : register(s0);\n"
|
sprintf(pprog, "uniform sampler samp0 : register(s0);\n"
|
||||||
"uniform float4 cColMatrix[5] : register(c%d);\n"
|
"uniform float4 cColMatrix[5] : register(c%d);\n"
|
||||||
"void main(\n"
|
"void main(\n"
|
||||||
"out float4 ocol0 : COLOR0,\n"
|
"out float4 ocol0 : COLOR0,\n"
|
||||||
"in float4 uv0 : TEXCOORD0,\n"
|
"in float4 uv0 : TEXCOORD0,\n"
|
||||||
"in float4 uv1 : TEXCOORD1,\n"
|
"in float4 uv1 : TEXCOORD1,\n"
|
||||||
"in float4 uv2 : TEXCOORD2,\n"
|
"in float4 uv2 : TEXCOORD2,\n"
|
||||||
"in float4 uv3 : TEXCOORD3){\n"
|
"in float4 uv3 : TEXCOORD3){\n"
|
||||||
"float4 texcol = (tex2D(samp0,uv1.xy) + tex2D(samp0,uv1.wz) + tex2D(samp0,uv2.xy) + tex2D(samp0,uv2.wz))*0.25f;\n"
|
"float4 texcol = (tex2D(samp0,uv1.xy) + tex2D(samp0,uv1.wz) + tex2D(samp0,uv2.xy) + tex2D(samp0,uv2.wz))*0.25f;\n"
|
||||||
"float4 EncodedDepth = frac((texcol.r * (16777215.0f/16777216.0f)) * float4(1.0f,255.0f,255.0f*255.0f,255.0f*255.0f*255.0f));\n"
|
"float4 EncodedDepth = frac((texcol.r * (16777215.0f/16777216.0f)) * float4(1.0f,255.0f,255.0f*255.0f,255.0f*255.0f*255.0f));\n"
|
||||||
"texcol = float4((EncodedDepth.rgb * (16777216.0f/16777215.0f)),1.0f);\n"
|
"texcol = float4((EncodedDepth.rgb * (16777216.0f/16777215.0f)),1.0f);\n"
|
||||||
"ocol0 = float4(dot(texcol,cColMatrix[0]),dot(texcol,cColMatrix[1]),dot(texcol,cColMatrix[2]),dot(texcol,cColMatrix[3])) + cColMatrix[4];\n"
|
"ocol0 = float4(dot(texcol,cColMatrix[0]),dot(texcol,cColMatrix[1]),dot(texcol,cColMatrix[2]),dot(texcol,cColMatrix[3])) + cColMatrix[4];\n"
|
||||||
"}\n",C_COLORMATRIX);
|
"}\n",C_COLORMATRIX);
|
||||||
s_DepthMatrixProgram[2] = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog));
|
s_DepthMatrixProgram[2] = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog));
|
||||||
|
|
||||||
Clear();
|
Clear();
|
||||||
|
|
||||||
if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX)))
|
if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX)))
|
||||||
File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX));
|
File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX));
|
||||||
|
|
||||||
SETSTAT(stats.numPixelShadersCreated, 0);
|
SETSTAT(stats.numPixelShadersCreated, 0);
|
||||||
SETSTAT(stats.numPixelShadersAlive, 0);
|
SETSTAT(stats.numPixelShadersAlive, 0);
|
||||||
|
|
||||||
char cache_filename[MAX_PATH];
|
char cache_filename[MAX_PATH];
|
||||||
sprintf(cache_filename, "%sdx9-%s-ps.cache", File::GetUserPath(D_SHADERCACHE_IDX), g_globals->unique_id);
|
sprintf(cache_filename, "%sdx9-%s-ps.cache", File::GetUserPath(D_SHADERCACHE_IDX), g_globals->unique_id);
|
||||||
PixelShaderCacheInserter inserter;
|
PixelShaderCacheInserter inserter;
|
||||||
int read_items = g_ps_disk_cache.OpenAndRead(cache_filename, &inserter);
|
int read_items = g_ps_disk_cache.OpenAndRead(cache_filename, &inserter);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ONLY to be used during shutdown.
|
// ONLY to be used during shutdown.
|
||||||
void PixelShaderCache::Clear()
|
void PixelShaderCache::Clear()
|
||||||
{
|
{
|
||||||
PSCache::iterator iter = PixelShaders.begin();
|
PSCache::iterator iter = PixelShaders.begin();
|
||||||
for (; iter != PixelShaders.end(); ++iter)
|
for (; iter != PixelShaders.end(); ++iter)
|
||||||
iter->second.Destroy();
|
iter->second.Destroy();
|
||||||
PixelShaders.clear();
|
PixelShaders.clear();
|
||||||
|
|
||||||
memset(&last_pixel_shader_uid, 0xFF, sizeof(last_pixel_shader_uid));
|
memset(&last_pixel_shader_uid, 0xFF, sizeof(last_pixel_shader_uid));
|
||||||
}
|
}
|
||||||
|
|
||||||
PixelShaderCache::~PixelShaderCache()
|
PixelShaderCache::~PixelShaderCache()
|
||||||
{
|
{
|
||||||
for(int i = 0;i < MAX_SSAA_SHADERS; i++)
|
for(int i = 0;i < MAX_SSAA_SHADERS; i++)
|
||||||
{
|
{
|
||||||
if (s_ColorMatrixProgram[i]) s_ColorMatrixProgram[i]->Release();
|
if (s_ColorMatrixProgram[i]) s_ColorMatrixProgram[i]->Release();
|
||||||
s_ColorMatrixProgram[i] = NULL;
|
s_ColorMatrixProgram[i] = NULL;
|
||||||
if (s_ColorCopyProgram[i]) s_ColorCopyProgram[i]->Release();
|
if (s_ColorCopyProgram[i]) s_ColorCopyProgram[i]->Release();
|
||||||
s_ColorCopyProgram[i] = NULL;
|
s_ColorCopyProgram[i] = NULL;
|
||||||
if (s_DepthMatrixProgram[i]) s_DepthMatrixProgram[i]->Release();
|
if (s_DepthMatrixProgram[i]) s_DepthMatrixProgram[i]->Release();
|
||||||
s_DepthMatrixProgram[i] = NULL;
|
s_DepthMatrixProgram[i] = NULL;
|
||||||
}
|
}
|
||||||
if (s_ClearProgram) s_ClearProgram->Release();
|
if (s_ClearProgram) s_ClearProgram->Release();
|
||||||
s_ClearProgram = NULL;
|
s_ClearProgram = NULL;
|
||||||
|
|
||||||
Clear();
|
Clear();
|
||||||
g_ps_disk_cache.Sync();
|
g_ps_disk_cache.Sync();
|
||||||
g_ps_disk_cache.Close();
|
g_ps_disk_cache.Close();
|
||||||
|
|
||||||
unique_shaders.clear();
|
unique_shaders.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PixelShaderCache::SetShader(bool dstAlpha)
|
bool PixelShaderCache::SetShader(bool dstAlpha)
|
||||||
{
|
{
|
||||||
PIXELSHADERUID uid;
|
PIXELSHADERUID uid;
|
||||||
GetPixelShaderId(&uid, dstAlpha);
|
GetPixelShaderId(&uid, dstAlpha);
|
||||||
|
|
||||||
// Is the shader already set?
|
// Is the shader already set?
|
||||||
if (uid == last_pixel_shader_uid && PixelShaders[uid].frameCount == frameCount)
|
if (uid == last_pixel_shader_uid && PixelShaders[uid].frameCount == frameCount)
|
||||||
{
|
{
|
||||||
PSCache::const_iterator iter = PixelShaders.find(uid);
|
PSCache::const_iterator iter = PixelShaders.find(uid);
|
||||||
if (iter != PixelShaders.end() && iter->second.shader)
|
if (iter != PixelShaders.end() && iter->second.shader)
|
||||||
return true; // Sure, we're done.
|
return true; // Sure, we're done.
|
||||||
else
|
else
|
||||||
return false; // ?? something is wrong.
|
return false; // ?? something is wrong.
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(&last_pixel_shader_uid, &uid, sizeof(PIXELSHADERUID));
|
memcpy(&last_pixel_shader_uid, &uid, sizeof(PIXELSHADERUID));
|
||||||
|
|
||||||
// Is the shader already in the cache?
|
// Is the shader already in the cache?
|
||||||
PSCache::iterator iter;
|
PSCache::iterator iter;
|
||||||
iter = PixelShaders.find(uid);
|
iter = PixelShaders.find(uid);
|
||||||
if (iter != PixelShaders.end())
|
if (iter != PixelShaders.end())
|
||||||
{
|
{
|
||||||
iter->second.frameCount = frameCount;
|
iter->second.frameCount = frameCount;
|
||||||
const PSCacheEntry &entry = iter->second;
|
const PSCacheEntry &entry = iter->second;
|
||||||
last_entry = &entry;
|
last_entry = &entry;
|
||||||
|
|
||||||
if (entry.shader)
|
if (entry.shader)
|
||||||
{
|
{
|
||||||
D3D::SetPixelShader(entry.shader);
|
D3D::SetPixelShader(entry.shader);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// OK, need to generate and compile it.
|
// OK, need to generate and compile it.
|
||||||
const char *code = GeneratePixelShaderCode(dstAlpha, API_D3D9);
|
const char *code = GeneratePixelShaderCode(dstAlpha, API_D3D9);
|
||||||
|
|
||||||
u32 code_hash = HashAdler32((const u8 *)code, strlen(code));
|
u32 code_hash = HashAdler32((const u8 *)code, strlen(code));
|
||||||
unique_shaders.insert(code_hash);
|
unique_shaders.insert(code_hash);
|
||||||
SETSTAT(stats.numUniquePixelShaders, unique_shaders.size());
|
SETSTAT(stats.numUniquePixelShaders, unique_shaders.size());
|
||||||
|
|
||||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||||
if (g_ActiveConfig.iLog & CONF_SAVESHADERS && code) {
|
if (g_ActiveConfig.iLog & CONF_SAVESHADERS && code) {
|
||||||
static int counter = 0;
|
static int counter = 0;
|
||||||
char szTemp[MAX_PATH];
|
char szTemp[MAX_PATH];
|
||||||
sprintf(szTemp, "%sps_%04i.txt", File::GetUserPath(D_DUMP_IDX), counter++);
|
sprintf(szTemp, "%sps_%04i.txt", File::GetUserPath(D_DUMP_IDX), counter++);
|
||||||
|
|
||||||
SaveData(szTemp, code);
|
SaveData(szTemp, code);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
u8 *bytecode = 0;
|
u8 *bytecode = 0;
|
||||||
int bytecodelen = 0;
|
int bytecodelen = 0;
|
||||||
if (!D3D::CompilePixelShader(code, (int)strlen(code), &bytecode, &bytecodelen)) {
|
if (!D3D::CompilePixelShader(code, (int)strlen(code), &bytecode, &bytecodelen)) {
|
||||||
if (g_ActiveConfig.bShowShaderErrors)
|
if (g_ActiveConfig.bShowShaderErrors)
|
||||||
{
|
{
|
||||||
PanicAlert("Failed to compile Pixel Shader:\n\n%s", code);
|
PanicAlert("Failed to compile Pixel Shader:\n\n%s", code);
|
||||||
static int counter = 0;
|
static int counter = 0;
|
||||||
char szTemp[MAX_PATH];
|
char szTemp[MAX_PATH];
|
||||||
sprintf(szTemp, "%sBADps_%04i.txt", File::GetUserPath(D_DUMP_IDX), counter++);
|
sprintf(szTemp, "%sBADps_%04i.txt", File::GetUserPath(D_DUMP_IDX), counter++);
|
||||||
SaveData(szTemp, code);
|
SaveData(szTemp, code);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Here we have the UID and the byte code. Insert it into the disk cache.
|
// Here we have the UID and the byte code. Insert it into the disk cache.
|
||||||
g_ps_disk_cache.Append((u8 *)&uid, sizeof(uid), bytecode, bytecodelen);
|
g_ps_disk_cache.Append((u8 *)&uid, sizeof(uid), bytecode, bytecodelen);
|
||||||
g_ps_disk_cache.Sync();
|
g_ps_disk_cache.Sync();
|
||||||
|
|
||||||
// And insert it into the shader cache.
|
// And insert it into the shader cache.
|
||||||
bool result = InsertByteCode(uid, bytecode, bytecodelen, true);
|
bool result = InsertByteCode(uid, bytecode, bytecodelen, true);
|
||||||
delete [] bytecode;
|
delete [] bytecode;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PixelShaderCache::InsertByteCode(const PIXELSHADERUID &uid, const u8 *bytecode, int bytecodelen, bool activate) {
|
bool PixelShaderCache::InsertByteCode(const PIXELSHADERUID &uid, const u8 *bytecode, int bytecodelen, bool activate) {
|
||||||
LPDIRECT3DPIXELSHADER9 shader = D3D::CreatePixelShaderFromByteCode(bytecode, bytecodelen);
|
LPDIRECT3DPIXELSHADER9 shader = D3D::CreatePixelShaderFromByteCode(bytecode, bytecodelen);
|
||||||
|
|
||||||
// Make an entry in the table
|
// Make an entry in the table
|
||||||
PSCacheEntry newentry;
|
PSCacheEntry newentry;
|
||||||
newentry.shader = shader;
|
newentry.shader = shader;
|
||||||
newentry.frameCount = frameCount;
|
newentry.frameCount = frameCount;
|
||||||
PixelShaders[uid] = newentry;
|
PixelShaders[uid] = newentry;
|
||||||
last_entry = &PixelShaders[uid];
|
last_entry = &PixelShaders[uid];
|
||||||
|
|
||||||
if (!shader) {
|
if (!shader) {
|
||||||
// INCSTAT(stats.numPixelShadersFailed);
|
// INCSTAT(stats.numPixelShadersFailed);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
INCSTAT(stats.numPixelShadersCreated);
|
INCSTAT(stats.numPixelShadersCreated);
|
||||||
SETSTAT(stats.numPixelShadersAlive, (int)PixelShaders.size());
|
SETSTAT(stats.numPixelShadersAlive, (int)PixelShaders.size());
|
||||||
if (activate)
|
if (activate)
|
||||||
{
|
{
|
||||||
D3D::SetPixelShader(shader);
|
D3D::SetPixelShader(shader);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||||
std::string PixelShaderCache::GetCurrentShaderCode()
|
std::string PixelShaderCache::GetCurrentShaderCode()
|
||||||
{
|
{
|
||||||
if (last_entry)
|
if (last_entry)
|
||||||
return last_entry->code;
|
return last_entry->code;
|
||||||
else
|
else
|
||||||
return "(no shader)\n";
|
return "(no shader)\n";
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,89 +1,89 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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/
|
||||||
|
|
||||||
#ifndef _PIXELSHADERCACHE_H
|
#ifndef _PIXELSHADERCACHE_H
|
||||||
#define _PIXELSHADERCACHE_H
|
#define _PIXELSHADERCACHE_H
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "LinearDiskCache.h"
|
#include "LinearDiskCache.h"
|
||||||
#include "DX9_D3DBase.h"
|
#include "DX9_D3DBase.h"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include "PixelShaderGen.h"
|
#include "PixelShaderGen.h"
|
||||||
#include "VertexShaderGen.h"
|
#include "VertexShaderGen.h"
|
||||||
|
|
||||||
#include "../PixelShaderCache.h"
|
#include "../PixelShaderCache.h"
|
||||||
|
|
||||||
namespace DX9
|
namespace DX9
|
||||||
{
|
{
|
||||||
|
|
||||||
typedef u32 tevhash;
|
typedef u32 tevhash;
|
||||||
|
|
||||||
tevhash GetCurrentTEV();
|
tevhash GetCurrentTEV();
|
||||||
|
|
||||||
class PixelShaderCache : public ::PixelShaderCacheBase
|
class PixelShaderCache : public ::PixelShaderCacheBase
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
struct PSCacheEntry
|
struct PSCacheEntry
|
||||||
{
|
{
|
||||||
LPDIRECT3DPIXELSHADER9 shader;
|
LPDIRECT3DPIXELSHADER9 shader;
|
||||||
bool owns_shader;
|
bool owns_shader;
|
||||||
int frameCount;
|
int frameCount;
|
||||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||||
std::string code;
|
std::string code;
|
||||||
#endif
|
#endif
|
||||||
PSCacheEntry() : shader(NULL), owns_shader(true), frameCount(0) {}
|
PSCacheEntry() : shader(NULL), owns_shader(true), frameCount(0) {}
|
||||||
void Destroy()
|
void Destroy()
|
||||||
{
|
{
|
||||||
if (shader && owns_shader)
|
if (shader && owns_shader)
|
||||||
shader->Release();
|
shader->Release();
|
||||||
shader = NULL;
|
shader = NULL;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<PIXELSHADERUID, PSCacheEntry> PSCache;
|
typedef std::map<PIXELSHADERUID, PSCacheEntry> PSCache;
|
||||||
|
|
||||||
static PSCache PixelShaders;
|
static PSCache PixelShaders;
|
||||||
static const PSCacheEntry *last_entry;
|
static const PSCacheEntry *last_entry;
|
||||||
static void Clear();
|
static void Clear();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PixelShaderCache();
|
PixelShaderCache();
|
||||||
~PixelShaderCache();
|
~PixelShaderCache();
|
||||||
|
|
||||||
void SetPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4);
|
void SetPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4);
|
||||||
void SetPSConstant4fv(unsigned int const_number, const float* f);
|
void SetPSConstant4fv(unsigned int const_number, const float* f);
|
||||||
void SetMultiPSConstant4fv(unsigned int const_number, unsigned int count, const float* f);
|
void SetMultiPSConstant4fv(unsigned int const_number, unsigned int count, const float* f);
|
||||||
|
|
||||||
bool SetShader(bool dstAlpha);
|
bool SetShader(bool dstAlpha);
|
||||||
|
|
||||||
static bool InsertByteCode(const PIXELSHADERUID &uid, const u8 *bytecode, int bytecodelen, bool activate);
|
static bool InsertByteCode(const PIXELSHADERUID &uid, const u8 *bytecode, int bytecodelen, bool activate);
|
||||||
static LPDIRECT3DPIXELSHADER9 GetColorMatrixProgram(int SSAAMode);
|
static LPDIRECT3DPIXELSHADER9 GetColorMatrixProgram(int SSAAMode);
|
||||||
static LPDIRECT3DPIXELSHADER9 GetColorCopyProgram(int SSAAMode);
|
static LPDIRECT3DPIXELSHADER9 GetColorCopyProgram(int SSAAMode);
|
||||||
static LPDIRECT3DPIXELSHADER9 GetDepthMatrixProgram(int SSAAMode);
|
static LPDIRECT3DPIXELSHADER9 GetDepthMatrixProgram(int SSAAMode);
|
||||||
static LPDIRECT3DPIXELSHADER9 GetClearProgram();
|
static LPDIRECT3DPIXELSHADER9 GetClearProgram();
|
||||||
|
|
||||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||||
static std::string GetCurrentShaderCode();
|
static std::string GetCurrentShaderCode();
|
||||||
#endif
|
#endif
|
||||||
static LPDIRECT3DPIXELSHADER9 CompileCgShader(const char *pstrprogram);
|
static LPDIRECT3DPIXELSHADER9 CompileCgShader(const char *pstrprogram);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // _PIXELSHADERCACHE_H
|
#endif // _PIXELSHADERCACHE_H
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,58 +1,58 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "MathUtil.h"
|
#include "MathUtil.h"
|
||||||
|
|
||||||
#include "VideoCommon.h"
|
#include "VideoCommon.h"
|
||||||
#include "Renderer.h"
|
#include "Renderer.h"
|
||||||
#include "pluginspecs_video.h"
|
#include "pluginspecs_video.h"
|
||||||
|
|
||||||
namespace DX9
|
namespace DX9
|
||||||
{
|
{
|
||||||
|
|
||||||
class Renderer : public ::RendererBase
|
class Renderer : public ::RendererBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Renderer();
|
Renderer();
|
||||||
~Renderer();
|
~Renderer();
|
||||||
|
|
||||||
void ResetAPIState();
|
void ResetAPIState();
|
||||||
void RestoreAPIState();
|
void RestoreAPIState();
|
||||||
|
|
||||||
static void SetupDeviceObjects();
|
static void SetupDeviceObjects();
|
||||||
static void TeardownDeviceObjects();
|
static void TeardownDeviceObjects();
|
||||||
|
|
||||||
void SetColorMask();
|
void SetColorMask();
|
||||||
void SetBlendMode(bool forceUpdate);
|
void SetBlendMode(bool forceUpdate);
|
||||||
bool SetScissorRect();
|
bool SetScissorRect();
|
||||||
|
|
||||||
void SetGenerationMode();
|
void SetGenerationMode();
|
||||||
void SetDepthMode();
|
void SetDepthMode();
|
||||||
void SetLogicOpMode();
|
void SetLogicOpMode();
|
||||||
void SetSamplerState(int stage,int texindex);
|
void SetSamplerState(int stage,int texindex);
|
||||||
void SetDitherMode();
|
void SetDitherMode();
|
||||||
void SetLineWidth();
|
void SetLineWidth();
|
||||||
|
|
||||||
u32 AccessEFB(EFBAccessType type, int x, int y);
|
u32 AccessEFB(EFBAccessType type, int x, int y);
|
||||||
|
|
||||||
void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z);
|
void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z);
|
||||||
void UpdateViewport();
|
void UpdateViewport();
|
||||||
|
|
||||||
// virtual funcs used by RendererBase::Swap
|
// virtual funcs used by RendererBase::Swap
|
||||||
void PrepareXFBCopy(const TargetRectangle &dst_rect);
|
void PrepareXFBCopy(const TargetRectangle &dst_rect);
|
||||||
void Draw(const XFBSourceBase* xfbSource, const TargetRectangle& sourceRc,
|
void Draw(const XFBSourceBase* xfbSource, const TargetRectangle& sourceRc,
|
||||||
const MathUtil::Rectangle<float>& drawRc, const EFBRectangle& rc);
|
const MathUtil::Rectangle<float>& drawRc, const EFBRectangle& rc);
|
||||||
void EndFrame();
|
void EndFrame();
|
||||||
void Present();
|
void Present();
|
||||||
bool CheckForResize();
|
bool CheckForResize();
|
||||||
void GetBackBufferSize(int* w, int* h);
|
void GetBackBufferSize(int* w, int* h);
|
||||||
void RecreateFramebufferManger();
|
void RecreateFramebufferManger();
|
||||||
void BeginFrame();
|
void BeginFrame();
|
||||||
|
|
||||||
void Swap(u32, FieldType, u32, u32, const EFBRectangle&);
|
void Swap(u32, FieldType, u32, u32, const EFBRectangle&);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool IS_AMD;
|
static bool IS_AMD;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,207 +1,207 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
#include <d3dx9.h>
|
#include <d3dx9.h>
|
||||||
|
|
||||||
#include "Statistics.h"
|
#include "Statistics.h"
|
||||||
#include "MemoryUtil.h"
|
#include "MemoryUtil.h"
|
||||||
#include "Hash.h"
|
#include "Hash.h"
|
||||||
|
|
||||||
#include "CommonPaths.h"
|
#include "CommonPaths.h"
|
||||||
#include "FileUtil.h"
|
#include "FileUtil.h"
|
||||||
|
|
||||||
#include "DX9_D3DBase.h"
|
#include "DX9_D3DBase.h"
|
||||||
#include "DX9_D3DTexture.h"
|
#include "DX9_D3DTexture.h"
|
||||||
#include "DX9_D3DUtil.h"
|
#include "DX9_D3DUtil.h"
|
||||||
#include "DX9_FramebufferManager.h"
|
#include "DX9_FramebufferManager.h"
|
||||||
#include "DX9_PixelShaderCache.h"
|
#include "DX9_PixelShaderCache.h"
|
||||||
#include "PixelShaderManager.h"
|
#include "PixelShaderManager.h"
|
||||||
#include "VertexShaderManager.h"
|
#include "VertexShaderManager.h"
|
||||||
#include "DX9_VertexShaderCache.h"
|
#include "DX9_VertexShaderCache.h"
|
||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
|
|
||||||
#include "DX9_Render.h"
|
#include "DX9_Render.h"
|
||||||
|
|
||||||
#include "TextureDecoder.h"
|
#include "TextureDecoder.h"
|
||||||
#include "DX9_TextureCache.h"
|
#include "DX9_TextureCache.h"
|
||||||
#include "HiresTextures.h"
|
#include "HiresTextures.h"
|
||||||
#include "DX9_TextureConverter.h"
|
#include "DX9_TextureConverter.h"
|
||||||
|
|
||||||
#include "../Main.h"
|
#include "../Main.h"
|
||||||
|
|
||||||
//#include "debugger/debugger.h"
|
//#include "debugger/debugger.h"
|
||||||
|
|
||||||
namespace DX9
|
namespace DX9
|
||||||
{
|
{
|
||||||
|
|
||||||
TextureCache::TCacheEntry::TCacheEntry(LPDIRECT3DTEXTURE9 _texture)
|
TextureCache::TCacheEntry::TCacheEntry(LPDIRECT3DTEXTURE9 _texture)
|
||||||
: texture(_texture), isDynamic(false)
|
: texture(_texture), isDynamic(false)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureCache::TCacheEntry::~TCacheEntry()
|
TextureCache::TCacheEntry::~TCacheEntry()
|
||||||
{
|
{
|
||||||
texture->Release();
|
texture->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCache::TCacheEntry::Load(unsigned int width, unsigned int height,
|
void TextureCache::TCacheEntry::Load(unsigned int width, unsigned int height,
|
||||||
unsigned int expanded_width, unsigned int level)
|
unsigned int expanded_width, unsigned int level)
|
||||||
{
|
{
|
||||||
D3D::ReplaceTexture2D(texture, temp, width, height, expanded_width, d3d_fmt, swap_r_b, level);
|
D3D::ReplaceTexture2D(texture, temp, width, height, expanded_width, d3d_fmt, swap_r_b, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleByHalf,
|
void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleByHalf,
|
||||||
unsigned int cbufid, const float colmat[], const EFBRectangle &source_rect)
|
unsigned int cbufid, const float colmat[], const EFBRectangle &source_rect)
|
||||||
{
|
{
|
||||||
LPDIRECT3DSURFACE9 Rendersurf = NULL;
|
LPDIRECT3DSURFACE9 Rendersurf = NULL;
|
||||||
texture->GetSurfaceLevel(0, &Rendersurf);
|
texture->GetSurfaceLevel(0, &Rendersurf);
|
||||||
D3D::dev->SetDepthStencilSurface(NULL);
|
D3D::dev->SetDepthStencilSurface(NULL);
|
||||||
D3D::dev->SetRenderTarget(0, Rendersurf);
|
D3D::dev->SetRenderTarget(0, Rendersurf);
|
||||||
|
|
||||||
D3DVIEWPORT9 vp;
|
D3DVIEWPORT9 vp;
|
||||||
|
|
||||||
// Stretch picture with increased internal resolution
|
// Stretch picture with increased internal resolution
|
||||||
vp.X = 0;
|
vp.X = 0;
|
||||||
vp.Y = 0;
|
vp.Y = 0;
|
||||||
vp.Width = Scaledw;
|
vp.Width = Scaledw;
|
||||||
vp.Height = Scaledh;
|
vp.Height = Scaledh;
|
||||||
vp.MinZ = 0.0f;
|
vp.MinZ = 0.0f;
|
||||||
vp.MaxZ = 1.0f;
|
vp.MaxZ = 1.0f;
|
||||||
D3D::dev->SetViewport(&vp);
|
D3D::dev->SetViewport(&vp);
|
||||||
RECT destrect;
|
RECT destrect;
|
||||||
destrect.bottom = Scaledh;
|
destrect.bottom = Scaledh;
|
||||||
destrect.left = 0;
|
destrect.left = 0;
|
||||||
destrect.right = Scaledw;
|
destrect.right = Scaledw;
|
||||||
destrect.top = 0;
|
destrect.top = 0;
|
||||||
|
|
||||||
const float* const fConstAdd = colmat + 16; // fConstAdd is the last 4 floats of colmat
|
const float* const fConstAdd = colmat + 16; // fConstAdd is the last 4 floats of colmat
|
||||||
PixelShaderManager::SetColorMatrix(colmat, fConstAdd); // set transformation
|
PixelShaderManager::SetColorMatrix(colmat, fConstAdd); // set transformation
|
||||||
TargetRectangle targetSource = Renderer::ConvertEFBRectangle(source_rect);
|
TargetRectangle targetSource = Renderer::ConvertEFBRectangle(source_rect);
|
||||||
RECT sourcerect;
|
RECT sourcerect;
|
||||||
sourcerect.bottom = targetSource.bottom;
|
sourcerect.bottom = targetSource.bottom;
|
||||||
sourcerect.left = targetSource.left;
|
sourcerect.left = targetSource.left;
|
||||||
sourcerect.right = targetSource.right;
|
sourcerect.right = targetSource.right;
|
||||||
sourcerect.top = targetSource.top;
|
sourcerect.top = targetSource.top;
|
||||||
|
|
||||||
if (bFromZBuffer)
|
if (bFromZBuffer)
|
||||||
{
|
{
|
||||||
if (bScaleByHalf || g_ActiveConfig.iMultisampleMode)
|
if (bScaleByHalf || g_ActiveConfig.iMultisampleMode)
|
||||||
{
|
{
|
||||||
D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
||||||
D3D::ChangeSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
D3D::ChangeSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
|
D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
|
||||||
D3D::ChangeSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
|
D3D::ChangeSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
||||||
D3D::ChangeSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
D3D::ChangeSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
const LPDIRECT3DTEXTURE9 read_texture = bFromZBuffer ?
|
const LPDIRECT3DTEXTURE9 read_texture = bFromZBuffer ?
|
||||||
FramebufferManager::GetEFBDepthTexture(source_rect) :
|
FramebufferManager::GetEFBDepthTexture(source_rect) :
|
||||||
FramebufferManager::GetEFBColorTexture(source_rect);
|
FramebufferManager::GetEFBColorTexture(source_rect);
|
||||||
|
|
||||||
D3DFORMAT bformat = FramebufferManager::GetEFBDepthRTSurfaceFormat();
|
D3DFORMAT bformat = FramebufferManager::GetEFBDepthRTSurfaceFormat();
|
||||||
int SSAAMode = g_ActiveConfig.iMultisampleMode;
|
int SSAAMode = g_ActiveConfig.iMultisampleMode;
|
||||||
|
|
||||||
D3D::drawShadedTexQuad(read_texture, &sourcerect,
|
D3D::drawShadedTexQuad(read_texture, &sourcerect,
|
||||||
Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight(),
|
Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight(),
|
||||||
Scaledw, Scaledh,
|
Scaledw, Scaledh,
|
||||||
((bformat != FOURCC_RAWZ && bformat != D3DFMT_D24X8) && bFromZBuffer) ?
|
((bformat != FOURCC_RAWZ && bformat != D3DFMT_D24X8) && bFromZBuffer) ?
|
||||||
PixelShaderCache::GetDepthMatrixProgram(SSAAMode) :
|
PixelShaderCache::GetDepthMatrixProgram(SSAAMode) :
|
||||||
PixelShaderCache::GetColorMatrixProgram(SSAAMode),
|
PixelShaderCache::GetColorMatrixProgram(SSAAMode),
|
||||||
VertexShaderCache::GetSimpleVertexShader(SSAAMode));
|
VertexShaderCache::GetSimpleVertexShader(SSAAMode));
|
||||||
|
|
||||||
Rendersurf->Release();
|
Rendersurf->Release();
|
||||||
|
|
||||||
D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER);
|
D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER);
|
||||||
D3D::RefreshSamplerState(0, D3DSAMP_MAGFILTER);
|
D3D::RefreshSamplerState(0, D3DSAMP_MAGFILTER);
|
||||||
D3D::SetTexture(0,NULL);
|
D3D::SetTexture(0,NULL);
|
||||||
D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface());
|
D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface());
|
||||||
D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface());
|
D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface());
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCache::TCacheEntry::Bind(unsigned int stage)
|
void TextureCache::TCacheEntry::Bind(unsigned int stage)
|
||||||
{
|
{
|
||||||
D3D::SetTexture(stage, texture);
|
D3D::SetTexture(stage, texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureCache::TCacheEntryBase* TextureCache::CreateTexture(unsigned int width, unsigned int height,
|
TextureCache::TCacheEntryBase* TextureCache::CreateTexture(unsigned int width, unsigned int height,
|
||||||
unsigned int expanded_width, unsigned int tex_levels, PC_TexFormat pcfmt)
|
unsigned int expanded_width, unsigned int tex_levels, PC_TexFormat pcfmt)
|
||||||
{
|
{
|
||||||
D3DFORMAT d3d_fmt;
|
D3DFORMAT d3d_fmt;
|
||||||
bool swap_r_b = false;
|
bool swap_r_b = false;
|
||||||
|
|
||||||
switch (pcfmt)
|
switch (pcfmt)
|
||||||
{
|
{
|
||||||
case PC_TEX_FMT_BGRA32:
|
case PC_TEX_FMT_BGRA32:
|
||||||
d3d_fmt = D3DFMT_A8R8G8B8;
|
d3d_fmt = D3DFMT_A8R8G8B8;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PC_TEX_FMT_RGBA32:
|
case PC_TEX_FMT_RGBA32:
|
||||||
d3d_fmt = D3DFMT_A8R8G8B8;
|
d3d_fmt = D3DFMT_A8R8G8B8;
|
||||||
swap_r_b = true;
|
swap_r_b = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PC_TEX_FMT_RGB565:
|
case PC_TEX_FMT_RGB565:
|
||||||
d3d_fmt = D3DFMT_R5G6B5;
|
d3d_fmt = D3DFMT_R5G6B5;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PC_TEX_FMT_IA4_AS_IA8:
|
case PC_TEX_FMT_IA4_AS_IA8:
|
||||||
d3d_fmt = D3DFMT_A8L8;
|
d3d_fmt = D3DFMT_A8L8;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PC_TEX_FMT_I8:
|
case PC_TEX_FMT_I8:
|
||||||
case PC_TEX_FMT_I4_AS_I8:
|
case PC_TEX_FMT_I4_AS_I8:
|
||||||
// A hack which means the format is a packed
|
// A hack which means the format is a packed
|
||||||
// 8-bit intensity texture. It is unpacked
|
// 8-bit intensity texture. It is unpacked
|
||||||
// to A8L8 in D3DTexture.cpp
|
// to A8L8 in D3DTexture.cpp
|
||||||
d3d_fmt = D3DFMT_A8P8;
|
d3d_fmt = D3DFMT_A8P8;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PC_TEX_FMT_IA8:
|
case PC_TEX_FMT_IA8:
|
||||||
d3d_fmt = D3DFMT_A8L8;
|
d3d_fmt = D3DFMT_A8L8;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PC_TEX_FMT_DXT1:
|
case PC_TEX_FMT_DXT1:
|
||||||
d3d_fmt = D3DFMT_DXT1;
|
d3d_fmt = D3DFMT_DXT1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
TCacheEntry* entry = new TCacheEntry(D3D::CreateTexture2D(temp, width, height, expanded_width, d3d_fmt, swap_r_b, tex_levels));
|
TCacheEntry* entry = new TCacheEntry(D3D::CreateTexture2D(temp, width, height, expanded_width, d3d_fmt, swap_r_b, tex_levels));
|
||||||
entry->swap_r_b = swap_r_b;
|
entry->swap_r_b = swap_r_b;
|
||||||
entry->d3d_fmt = d3d_fmt;
|
entry->d3d_fmt = d3d_fmt;
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureCache::TCacheEntryBase* TextureCache::CreateRenderTargetTexture(int scaled_tex_w, int scaled_tex_h)
|
TextureCache::TCacheEntryBase* TextureCache::CreateRenderTargetTexture(int scaled_tex_w, int scaled_tex_h)
|
||||||
{
|
{
|
||||||
LPDIRECT3DTEXTURE9 texture;
|
LPDIRECT3DTEXTURE9 texture;
|
||||||
D3D::dev->CreateTexture(scaled_tex_w, scaled_tex_h, 1, D3DUSAGE_RENDERTARGET,
|
D3D::dev->CreateTexture(scaled_tex_w, scaled_tex_h, 1, D3DUSAGE_RENDERTARGET,
|
||||||
D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, 0);
|
D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, 0);
|
||||||
|
|
||||||
return new TCacheEntry(texture);
|
return new TCacheEntry(texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,67 +1,67 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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/
|
||||||
|
|
||||||
#ifndef _TEXTURECACHE_H
|
#ifndef _TEXTURECACHE_H
|
||||||
#define _TEXTURECACHE_H
|
#define _TEXTURECACHE_H
|
||||||
|
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include "DX9_D3DBase.h"
|
#include "DX9_D3DBase.h"
|
||||||
#include "VideoCommon.h"
|
#include "VideoCommon.h"
|
||||||
#include "BPMemory.h"
|
#include "BPMemory.h"
|
||||||
|
|
||||||
#include "../TextureCache.h"
|
#include "../TextureCache.h"
|
||||||
|
|
||||||
namespace DX9
|
namespace DX9
|
||||||
{
|
{
|
||||||
|
|
||||||
class TextureCache : public TextureCacheBase
|
class TextureCache : public TextureCacheBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
struct TCacheEntry : TCacheEntryBase
|
struct TCacheEntry : TCacheEntryBase
|
||||||
{
|
{
|
||||||
LPDIRECT3DTEXTURE9 texture;
|
LPDIRECT3DTEXTURE9 texture;
|
||||||
|
|
||||||
D3DFORMAT d3d_fmt;
|
D3DFORMAT d3d_fmt;
|
||||||
bool swap_r_b;
|
bool swap_r_b;
|
||||||
bool isDynamic; // mofified from cpu
|
bool isDynamic; // mofified from cpu
|
||||||
|
|
||||||
TCacheEntry(LPDIRECT3DTEXTURE9 _texture);
|
TCacheEntry(LPDIRECT3DTEXTURE9 _texture);
|
||||||
~TCacheEntry();
|
~TCacheEntry();
|
||||||
|
|
||||||
void Load(unsigned int width, unsigned int height,
|
void Load(unsigned int width, unsigned int height,
|
||||||
unsigned int expanded_width, unsigned int levels);
|
unsigned int expanded_width, unsigned int levels);
|
||||||
|
|
||||||
void FromRenderTarget(bool bFromZBuffer, bool bScaleByHalf,
|
void FromRenderTarget(bool bFromZBuffer, bool bScaleByHalf,
|
||||||
unsigned int cbufid, const float colmat[], const EFBRectangle &source_rect);
|
unsigned int cbufid, const float colmat[], const EFBRectangle &source_rect);
|
||||||
|
|
||||||
void Bind(unsigned int stage);
|
void Bind(unsigned int stage);
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
TCacheEntryBase* CreateTexture(unsigned int width, unsigned int height,
|
TCacheEntryBase* CreateTexture(unsigned int width, unsigned int height,
|
||||||
unsigned int expanded_width, unsigned int tex_levels, PC_TexFormat pcfmt);
|
unsigned int expanded_width, unsigned int tex_levels, PC_TexFormat pcfmt);
|
||||||
|
|
||||||
TCacheEntryBase* CreateRenderTargetTexture(int scaled_tex_w, int scaled_tex_h);
|
TCacheEntryBase* CreateRenderTargetTexture(int scaled_tex_w, int scaled_tex_h);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,53 +1,53 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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/
|
||||||
|
|
||||||
#ifndef _TEXTURECONVERTER_H_
|
#ifndef _TEXTURECONVERTER_H_
|
||||||
#define _TEXTURECONVERTER_H_
|
#define _TEXTURECONVERTER_H_
|
||||||
|
|
||||||
#include "VideoCommon.h"
|
#include "VideoCommon.h"
|
||||||
#include "DX9_D3DBase.h"
|
#include "DX9_D3DBase.h"
|
||||||
#include "DX9_D3DTexture.h"
|
#include "DX9_D3DTexture.h"
|
||||||
#include "DX9_D3DUtil.h"
|
#include "DX9_D3DUtil.h"
|
||||||
#include "DX9_D3DShader.h"
|
#include "DX9_D3DShader.h"
|
||||||
|
|
||||||
namespace DX9
|
namespace DX9
|
||||||
{
|
{
|
||||||
|
|
||||||
// Converts textures between formats
|
// Converts textures between formats
|
||||||
// TODO: support multiple texture formats
|
// TODO: support multiple texture formats
|
||||||
namespace TextureConverter
|
namespace TextureConverter
|
||||||
{
|
{
|
||||||
|
|
||||||
void Init();
|
void Init();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
|
||||||
void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt,
|
void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt,
|
||||||
u32 copyfmt, int bScaleByHalf, const EFBRectangle& source);
|
u32 copyfmt, int bScaleByHalf, const EFBRectangle& source);
|
||||||
|
|
||||||
void EncodeToRamYUYV(LPDIRECT3DTEXTURE9 srcTexture, const TargetRectangle& sourceRc,
|
void EncodeToRamYUYV(LPDIRECT3DTEXTURE9 srcTexture, const TargetRectangle& sourceRc,
|
||||||
u8* destAddr, int dstWidth, int dstHeight);
|
u8* destAddr, int dstWidth, int dstHeight);
|
||||||
|
|
||||||
void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, LPDIRECT3DTEXTURE9 destTexture);
|
void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, LPDIRECT3DTEXTURE9 destTexture);
|
||||||
|
|
||||||
u64 EncodeToRamFromTexture(u32 address,LPDIRECT3DTEXTURE9 source_texture,u32 SourceW, u32 SourceH,float MValueX,float MValueY,float Xstride, float Ystride , bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source);
|
u64 EncodeToRamFromTexture(u32 address,LPDIRECT3DTEXTURE9 source_texture,u32 SourceW, u32 SourceH,float MValueX,float MValueY,float Xstride, float Ystride , bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // _TEXTURECONVERTER_H_
|
#endif // _TEXTURECONVERTER_H_
|
||||||
|
|||||||
@@ -1,135 +1,135 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "FileUtil.h"
|
#include "FileUtil.h"
|
||||||
|
|
||||||
#include "DX9_D3DBase.h"
|
#include "DX9_D3DBase.h"
|
||||||
#include "Fifo.h"
|
#include "Fifo.h"
|
||||||
#include "Statistics.h"
|
#include "Statistics.h"
|
||||||
#include "Profiler.h"
|
#include "Profiler.h"
|
||||||
#include "DX9_VertexManager.h"
|
#include "DX9_VertexManager.h"
|
||||||
#include "OpcodeDecoding.h"
|
#include "OpcodeDecoding.h"
|
||||||
#include "IndexGenerator.h"
|
#include "IndexGenerator.h"
|
||||||
#include "VertexShaderManager.h"
|
#include "VertexShaderManager.h"
|
||||||
#include "DX9_VertexShaderCache.h"
|
#include "DX9_VertexShaderCache.h"
|
||||||
#include "PixelShaderManager.h"
|
#include "PixelShaderManager.h"
|
||||||
#include "DX9_PixelShaderCache.h"
|
#include "DX9_PixelShaderCache.h"
|
||||||
#include "NativeVertexFormat.h"
|
#include "NativeVertexFormat.h"
|
||||||
#include "NativeVertexWriter.h"
|
#include "NativeVertexWriter.h"
|
||||||
#include "DX9_TextureCache.h"
|
#include "DX9_TextureCache.h"
|
||||||
|
|
||||||
#include "../Main.h"
|
#include "../Main.h"
|
||||||
|
|
||||||
#include "BPStructs.h"
|
#include "BPStructs.h"
|
||||||
#include "XFStructs.h"
|
#include "XFStructs.h"
|
||||||
|
|
||||||
//#include "debugger/debugger.h"
|
//#include "debugger/debugger.h"
|
||||||
|
|
||||||
namespace DX9
|
namespace DX9
|
||||||
{
|
{
|
||||||
|
|
||||||
using namespace D3D;
|
using namespace D3D;
|
||||||
|
|
||||||
// internal state for loading vertices
|
// internal state for loading vertices
|
||||||
extern NativeVertexFormat *g_nativeVertexFmt;
|
extern NativeVertexFormat *g_nativeVertexFmt;
|
||||||
|
|
||||||
inline void DumpBadShaders()
|
inline void DumpBadShaders()
|
||||||
{
|
{
|
||||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||||
std::string error_shaders;
|
std::string error_shaders;
|
||||||
error_shaders.append(VertexShaderCache::GetCurrentShaderCode());
|
error_shaders.append(VertexShaderCache::GetCurrentShaderCode());
|
||||||
error_shaders.append(PixelShaderCache::GetCurrentShaderCode());
|
error_shaders.append(PixelShaderCache::GetCurrentShaderCode());
|
||||||
char filename[512] = "bad_shader_combo_0.txt";
|
char filename[512] = "bad_shader_combo_0.txt";
|
||||||
int which = 0;
|
int which = 0;
|
||||||
while (File::Exists(filename))
|
while (File::Exists(filename))
|
||||||
{
|
{
|
||||||
which++;
|
which++;
|
||||||
sprintf(filename, "bad_shader_combo_%i.txt", which);
|
sprintf(filename, "bad_shader_combo_%i.txt", which);
|
||||||
}
|
}
|
||||||
File::WriteStringToFile(true, error_shaders, filename);
|
File::WriteStringToFile(true, error_shaders, filename);
|
||||||
PanicAlert("DrawIndexedPrimitiveUP failed. Shaders written to %s", filename);
|
PanicAlert("DrawIndexedPrimitiveUP failed. Shaders written to %s", filename);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexManager::Draw(u32 stride, bool alphapass)
|
void VertexManager::Draw(u32 stride, bool alphapass)
|
||||||
{
|
{
|
||||||
if (alphapass)
|
if (alphapass)
|
||||||
{
|
{
|
||||||
DWORD write = 0;
|
DWORD write = 0;
|
||||||
if (false == g_pixel_shader_cache->SetShader(true))
|
if (false == g_pixel_shader_cache->SetShader(true))
|
||||||
{
|
{
|
||||||
//DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");});
|
//DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");});
|
||||||
//goto shader_fail;
|
//goto shader_fail;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// update alpha only
|
// update alpha only
|
||||||
D3D::ChangeRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA);
|
D3D::ChangeRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA);
|
||||||
D3D::ChangeRenderState(D3DRS_ALPHABLENDENABLE, false);
|
D3D::ChangeRenderState(D3DRS_ALPHABLENDENABLE, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IndexGenerator::GetNumTriangles() > 0)
|
if (IndexGenerator::GetNumTriangles() > 0)
|
||||||
{
|
{
|
||||||
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
|
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
|
||||||
D3DPT_TRIANGLELIST,
|
D3DPT_TRIANGLELIST,
|
||||||
0, IndexGenerator::GetNumVerts(), IndexGenerator::GetNumTriangles(),
|
0, IndexGenerator::GetNumVerts(), IndexGenerator::GetNumTriangles(),
|
||||||
TIBuffer,
|
TIBuffer,
|
||||||
D3DFMT_INDEX16,
|
D3DFMT_INDEX16,
|
||||||
LocalVBuffer,
|
LocalVBuffer,
|
||||||
stride)))
|
stride)))
|
||||||
{
|
{
|
||||||
DumpBadShaders();
|
DumpBadShaders();
|
||||||
}
|
}
|
||||||
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
|
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
|
||||||
}
|
}
|
||||||
if (IndexGenerator::GetNumLines() > 0)
|
if (IndexGenerator::GetNumLines() > 0)
|
||||||
{
|
{
|
||||||
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
|
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
|
||||||
D3DPT_LINELIST,
|
D3DPT_LINELIST,
|
||||||
0, IndexGenerator::GetNumVerts(), IndexGenerator::GetNumLines(),
|
0, IndexGenerator::GetNumVerts(), IndexGenerator::GetNumLines(),
|
||||||
LIBuffer,
|
LIBuffer,
|
||||||
D3DFMT_INDEX16,
|
D3DFMT_INDEX16,
|
||||||
LocalVBuffer,
|
LocalVBuffer,
|
||||||
stride)))
|
stride)))
|
||||||
{
|
{
|
||||||
DumpBadShaders();
|
DumpBadShaders();
|
||||||
}
|
}
|
||||||
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
|
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
|
||||||
}
|
}
|
||||||
if (IndexGenerator::GetNumPoints() > 0)
|
if (IndexGenerator::GetNumPoints() > 0)
|
||||||
{
|
{
|
||||||
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
|
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
|
||||||
D3DPT_POINTLIST,
|
D3DPT_POINTLIST,
|
||||||
0, IndexGenerator::GetNumVerts(), IndexGenerator::GetNumPoints(),
|
0, IndexGenerator::GetNumVerts(), IndexGenerator::GetNumPoints(),
|
||||||
PIBuffer,
|
PIBuffer,
|
||||||
D3DFMT_INDEX16,
|
D3DFMT_INDEX16,
|
||||||
LocalVBuffer,
|
LocalVBuffer,
|
||||||
stride)))
|
stride)))
|
||||||
{
|
{
|
||||||
DumpBadShaders();
|
DumpBadShaders();
|
||||||
}
|
}
|
||||||
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
|
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (alphapass)
|
if (alphapass)
|
||||||
{
|
{
|
||||||
D3D::RefreshRenderState(D3DRS_COLORWRITEENABLE);
|
D3D::RefreshRenderState(D3DRS_COLORWRITEENABLE);
|
||||||
D3D::RefreshRenderState(D3DRS_ALPHABLENDENABLE);
|
D3D::RefreshRenderState(D3DRS_ALPHABLENDENABLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -1,39 +1,39 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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/
|
||||||
|
|
||||||
#ifndef _VERTEXMANAGER_H
|
#ifndef _VERTEXMANAGER_H
|
||||||
#define _VERTEXMANAGER_H
|
#define _VERTEXMANAGER_H
|
||||||
|
|
||||||
#include "CPMemory.h"
|
#include "CPMemory.h"
|
||||||
#include "VertexLoader.h"
|
#include "VertexLoader.h"
|
||||||
|
|
||||||
#include "../VertexManager.h"
|
#include "../VertexManager.h"
|
||||||
|
|
||||||
namespace DX9
|
namespace DX9
|
||||||
{
|
{
|
||||||
|
|
||||||
class VertexManager : public ::VertexManagerBase
|
class VertexManager : public ::VertexManagerBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void Draw(u32 stride, bool alphapass);
|
void Draw(u32 stride, bool alphapass);
|
||||||
|
|
||||||
NativeVertexFormat* CreateNativeVertexFormat();
|
NativeVertexFormat* CreateNativeVertexFormat();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,302 +1,302 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "FileUtil.h"
|
#include "FileUtil.h"
|
||||||
#include "LinearDiskCache.h"
|
#include "LinearDiskCache.h"
|
||||||
|
|
||||||
#include "DX9_D3DBase.h"
|
#include "DX9_D3DBase.h"
|
||||||
#include "DX9_D3DShader.h"
|
#include "DX9_D3DShader.h"
|
||||||
#include "Statistics.h"
|
#include "Statistics.h"
|
||||||
#include "Profiler.h"
|
#include "Profiler.h"
|
||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
#include "DX9_VertexShaderCache.h"
|
#include "DX9_VertexShaderCache.h"
|
||||||
#include "VertexLoader.h"
|
#include "VertexLoader.h"
|
||||||
#include "BPMemory.h"
|
#include "BPMemory.h"
|
||||||
#include "XFMemory.h"
|
#include "XFMemory.h"
|
||||||
|
|
||||||
//#include "debugger/debugger.h"
|
//#include "debugger/debugger.h"
|
||||||
|
|
||||||
#include "../Main.h"
|
#include "../Main.h"
|
||||||
|
|
||||||
namespace DX9
|
namespace DX9
|
||||||
{
|
{
|
||||||
|
|
||||||
VertexShaderCache::VSCache VertexShaderCache::vshaders;
|
VertexShaderCache::VSCache VertexShaderCache::vshaders;
|
||||||
const VertexShaderCache::VSCacheEntry *VertexShaderCache::last_entry;
|
const VertexShaderCache::VSCacheEntry *VertexShaderCache::last_entry;
|
||||||
|
|
||||||
#define MAX_SSAA_SHADERS 3
|
#define MAX_SSAA_SHADERS 3
|
||||||
|
|
||||||
static LPDIRECT3DVERTEXSHADER9 SimpleVertexShader[MAX_SSAA_SHADERS];
|
static LPDIRECT3DVERTEXSHADER9 SimpleVertexShader[MAX_SSAA_SHADERS];
|
||||||
static LPDIRECT3DVERTEXSHADER9 ClearVertexShader;
|
static LPDIRECT3DVERTEXSHADER9 ClearVertexShader;
|
||||||
|
|
||||||
LinearDiskCache g_vs_disk_cache;
|
LinearDiskCache g_vs_disk_cache;
|
||||||
|
|
||||||
LPDIRECT3DVERTEXSHADER9 VertexShaderCache::GetSimpleVertexShader(int level)
|
LPDIRECT3DVERTEXSHADER9 VertexShaderCache::GetSimpleVertexShader(int level)
|
||||||
{
|
{
|
||||||
return SimpleVertexShader[level % MAX_SSAA_SHADERS];
|
return SimpleVertexShader[level % MAX_SSAA_SHADERS];
|
||||||
}
|
}
|
||||||
|
|
||||||
LPDIRECT3DVERTEXSHADER9 VertexShaderCache::GetClearVertexShader()
|
LPDIRECT3DVERTEXSHADER9 VertexShaderCache::GetClearVertexShader()
|
||||||
{
|
{
|
||||||
return ClearVertexShader;
|
return ClearVertexShader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void VertexShaderCache::SetVSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4)
|
void VertexShaderCache::SetVSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4)
|
||||||
{
|
{
|
||||||
const float f[4] = { f1, f2, f3, f4 };
|
const float f[4] = { f1, f2, f3, f4 };
|
||||||
D3D::dev->SetVertexShaderConstantF(const_number, f, 1);
|
D3D::dev->SetVertexShaderConstantF(const_number, f, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexShaderCache::SetVSConstant4fv(unsigned int const_number, const float *f)
|
void VertexShaderCache::SetVSConstant4fv(unsigned int const_number, const float *f)
|
||||||
{
|
{
|
||||||
D3D::dev->SetVertexShaderConstantF(const_number, f, 1);
|
D3D::dev->SetVertexShaderConstantF(const_number, f, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexShaderCache::SetMultiVSConstant3fv(unsigned int const_number, unsigned int count, const float *f)
|
void VertexShaderCache::SetMultiVSConstant3fv(unsigned int const_number, unsigned int count, const float *f)
|
||||||
{
|
{
|
||||||
float buf[4*C_VENVCONST_END];
|
float buf[4*C_VENVCONST_END];
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
buf[4*i ] = *f++;
|
buf[4*i ] = *f++;
|
||||||
buf[4*i+1] = *f++;
|
buf[4*i+1] = *f++;
|
||||||
buf[4*i+2] = *f++;
|
buf[4*i+2] = *f++;
|
||||||
buf[4*i+3] = 0.f;
|
buf[4*i+3] = 0.f;
|
||||||
}
|
}
|
||||||
D3D::dev->SetVertexShaderConstantF(const_number, buf, count);
|
D3D::dev->SetVertexShaderConstantF(const_number, buf, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexShaderCache::SetMultiVSConstant4fv(unsigned int const_number, unsigned int count, const float *f)
|
void VertexShaderCache::SetMultiVSConstant4fv(unsigned int const_number, unsigned int count, const float *f)
|
||||||
{
|
{
|
||||||
D3D::dev->SetVertexShaderConstantF(const_number, f, count);
|
D3D::dev->SetVertexShaderConstantF(const_number, f, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
class VertexShaderCacheInserter : public LinearDiskCacheReader {
|
class VertexShaderCacheInserter : public LinearDiskCacheReader {
|
||||||
public:
|
public:
|
||||||
void Read(const u8 *key, int key_size, const u8 *value, int value_size)
|
void Read(const u8 *key, int key_size, const u8 *value, int value_size)
|
||||||
{
|
{
|
||||||
VERTEXSHADERUID uid;
|
VERTEXSHADERUID uid;
|
||||||
if (key_size != sizeof(uid)) {
|
if (key_size != sizeof(uid)) {
|
||||||
ERROR_LOG(VIDEO, "Wrong key size in vertex shader cache");
|
ERROR_LOG(VIDEO, "Wrong key size in vertex shader cache");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memcpy(&uid, key, key_size);
|
memcpy(&uid, key, key_size);
|
||||||
VertexShaderCache::InsertByteCode(uid, value, value_size, false);
|
VertexShaderCache::InsertByteCode(uid, value, value_size, false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
VertexShaderCache::VertexShaderCache()
|
VertexShaderCache::VertexShaderCache()
|
||||||
{
|
{
|
||||||
char* vProg = new char[2048];
|
char* vProg = new char[2048];
|
||||||
sprintf(vProg,"struct VSOUTPUT\n"
|
sprintf(vProg,"struct VSOUTPUT\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
"float4 vPosition : POSITION;\n"
|
"float4 vPosition : POSITION;\n"
|
||||||
"float2 vTexCoord : TEXCOORD0;\n"
|
"float2 vTexCoord : TEXCOORD0;\n"
|
||||||
"};\n"
|
"};\n"
|
||||||
"VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0)\n"
|
"VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
"VSOUTPUT OUT;\n"
|
"VSOUTPUT OUT;\n"
|
||||||
"OUT.vPosition = inPosition;\n"
|
"OUT.vPosition = inPosition;\n"
|
||||||
"OUT.vTexCoord = inTEX0;\n"
|
"OUT.vTexCoord = inTEX0;\n"
|
||||||
"return OUT;\n"
|
"return OUT;\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
|
|
||||||
SimpleVertexShader[0] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg));
|
SimpleVertexShader[0] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg));
|
||||||
|
|
||||||
sprintf(vProg,"struct VSOUTPUT\n"
|
sprintf(vProg,"struct VSOUTPUT\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
"float4 vPosition : POSITION;\n"
|
"float4 vPosition : POSITION;\n"
|
||||||
"float4 vColor0 : COLOR0;\n"
|
"float4 vColor0 : COLOR0;\n"
|
||||||
"};\n"
|
"};\n"
|
||||||
"VSOUTPUT main(float4 inPosition : POSITION,float4 inColor0: COLOR0)\n"
|
"VSOUTPUT main(float4 inPosition : POSITION,float4 inColor0: COLOR0)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
"VSOUTPUT OUT;\n"
|
"VSOUTPUT OUT;\n"
|
||||||
"OUT.vPosition = inPosition;\n"
|
"OUT.vPosition = inPosition;\n"
|
||||||
"OUT.vColor0 = inColor0;\n"
|
"OUT.vColor0 = inColor0;\n"
|
||||||
"return OUT;\n"
|
"return OUT;\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
|
|
||||||
ClearVertexShader = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg));
|
ClearVertexShader = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg));
|
||||||
|
|
||||||
sprintf(vProg, "struct VSOUTPUT\n"
|
sprintf(vProg, "struct VSOUTPUT\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
"float4 vPosition : POSITION;\n"
|
"float4 vPosition : POSITION;\n"
|
||||||
"float4 vTexCoord : TEXCOORD0;\n"
|
"float4 vTexCoord : TEXCOORD0;\n"
|
||||||
"float4 vTexCoord1 : TEXCOORD1;\n"
|
"float4 vTexCoord1 : TEXCOORD1;\n"
|
||||||
"};\n"
|
"};\n"
|
||||||
"VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float4 inTEX2 : TEXCOORD2)\n"
|
"VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float4 inTEX2 : TEXCOORD2)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
"VSOUTPUT OUT;"
|
"VSOUTPUT OUT;"
|
||||||
"OUT.vPosition = inPosition;\n"
|
"OUT.vPosition = inPosition;\n"
|
||||||
"OUT.vTexCoord = inTEX0.xyyx;\n"
|
"OUT.vTexCoord = inTEX0.xyyx;\n"
|
||||||
"OUT.vTexCoord1 = inTEX2;\n"
|
"OUT.vTexCoord1 = inTEX2;\n"
|
||||||
"return OUT;\n"
|
"return OUT;\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
SimpleVertexShader[1] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg));
|
SimpleVertexShader[1] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg));
|
||||||
|
|
||||||
sprintf(vProg, "struct VSOUTPUT\n"
|
sprintf(vProg, "struct VSOUTPUT\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
"float4 vPosition : POSITION;\n"
|
"float4 vPosition : POSITION;\n"
|
||||||
"float4 vTexCoord : TEXCOORD0;\n"
|
"float4 vTexCoord : TEXCOORD0;\n"
|
||||||
"float4 vTexCoord1 : TEXCOORD1;\n"
|
"float4 vTexCoord1 : TEXCOORD1;\n"
|
||||||
"float4 vTexCoord2 : TEXCOORD2;\n"
|
"float4 vTexCoord2 : TEXCOORD2;\n"
|
||||||
"float4 vTexCoord3 : TEXCOORD3;\n"
|
"float4 vTexCoord3 : TEXCOORD3;\n"
|
||||||
"};\n"
|
"};\n"
|
||||||
"VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float4 inTEX2 : TEXCOORD2)\n"
|
"VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float4 inTEX2 : TEXCOORD2)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
"VSOUTPUT OUT;"
|
"VSOUTPUT OUT;"
|
||||||
"OUT.vPosition = inPosition;\n"
|
"OUT.vPosition = inPosition;\n"
|
||||||
"OUT.vTexCoord = inTEX0.xyyx;\n"
|
"OUT.vTexCoord = inTEX0.xyyx;\n"
|
||||||
"OUT.vTexCoord1 = inTEX0.xyyx + (float4(-1.0f,-0.5f, 1.0f,-0.5f) * inTEX1.xyyx);\n"
|
"OUT.vTexCoord1 = inTEX0.xyyx + (float4(-1.0f,-0.5f, 1.0f,-0.5f) * inTEX1.xyyx);\n"
|
||||||
"OUT.vTexCoord2 = inTEX0.xyyx + (float4( 1.0f, 0.5f,-1.0f, 0.5f) * inTEX1.xyyx);\n"
|
"OUT.vTexCoord2 = inTEX0.xyyx + (float4( 1.0f, 0.5f,-1.0f, 0.5f) * inTEX1.xyyx);\n"
|
||||||
"OUT.vTexCoord3 = inTEX2;\n"
|
"OUT.vTexCoord3 = inTEX2;\n"
|
||||||
"return OUT;\n"
|
"return OUT;\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
SimpleVertexShader[2] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg));
|
SimpleVertexShader[2] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg));
|
||||||
|
|
||||||
Clear();
|
Clear();
|
||||||
delete [] vProg;
|
delete [] vProg;
|
||||||
|
|
||||||
if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX)))
|
if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX)))
|
||||||
File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX));
|
File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX));
|
||||||
|
|
||||||
SETSTAT(stats.numVertexShadersCreated, 0);
|
SETSTAT(stats.numVertexShadersCreated, 0);
|
||||||
SETSTAT(stats.numVertexShadersAlive, 0);
|
SETSTAT(stats.numVertexShadersAlive, 0);
|
||||||
|
|
||||||
char cache_filename[MAX_PATH];
|
char cache_filename[MAX_PATH];
|
||||||
sprintf(cache_filename, "%sdx9-%s-vs.cache", File::GetUserPath(D_SHADERCACHE_IDX), g_globals->unique_id);
|
sprintf(cache_filename, "%sdx9-%s-vs.cache", File::GetUserPath(D_SHADERCACHE_IDX), g_globals->unique_id);
|
||||||
VertexShaderCacheInserter inserter;
|
VertexShaderCacheInserter inserter;
|
||||||
int read_items = g_vs_disk_cache.OpenAndRead(cache_filename, &inserter);
|
int read_items = g_vs_disk_cache.OpenAndRead(cache_filename, &inserter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexShaderCache::Clear()
|
void VertexShaderCache::Clear()
|
||||||
{
|
{
|
||||||
VSCache::iterator
|
VSCache::iterator
|
||||||
iter = vshaders.begin(),
|
iter = vshaders.begin(),
|
||||||
vsend = vshaders.end();
|
vsend = vshaders.end();
|
||||||
for (; iter != vsend; ++iter)
|
for (; iter != vsend; ++iter)
|
||||||
iter->second.Destroy();
|
iter->second.Destroy();
|
||||||
|
|
||||||
vshaders.clear();
|
vshaders.clear();
|
||||||
|
|
||||||
memset(&last_vertex_shader_uid, 0xFF, sizeof(last_vertex_shader_uid));
|
memset(&last_vertex_shader_uid, 0xFF, sizeof(last_vertex_shader_uid));
|
||||||
}
|
}
|
||||||
|
|
||||||
VertexShaderCache::~VertexShaderCache()
|
VertexShaderCache::~VertexShaderCache()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < MAX_SSAA_SHADERS; i++)
|
for (int i = 0; i < MAX_SSAA_SHADERS; i++)
|
||||||
{
|
{
|
||||||
if (SimpleVertexShader[i])
|
if (SimpleVertexShader[i])
|
||||||
SimpleVertexShader[i]->Release();
|
SimpleVertexShader[i]->Release();
|
||||||
SimpleVertexShader[i] = NULL;
|
SimpleVertexShader[i] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ClearVertexShader)
|
if (ClearVertexShader)
|
||||||
ClearVertexShader->Release();
|
ClearVertexShader->Release();
|
||||||
|
|
||||||
ClearVertexShader = NULL;
|
ClearVertexShader = NULL;
|
||||||
|
|
||||||
g_vs_disk_cache.Sync();
|
g_vs_disk_cache.Sync();
|
||||||
g_vs_disk_cache.Close();
|
g_vs_disk_cache.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VertexShaderCache::SetShader(u32 components)
|
bool VertexShaderCache::SetShader(u32 components)
|
||||||
{
|
{
|
||||||
DVSTARTPROFILE();
|
DVSTARTPROFILE();
|
||||||
|
|
||||||
VERTEXSHADERUID uid;
|
VERTEXSHADERUID uid;
|
||||||
GetVertexShaderId(&uid, components);
|
GetVertexShaderId(&uid, components);
|
||||||
if (uid == last_vertex_shader_uid && vshaders[uid].frameCount == frameCount)
|
if (uid == last_vertex_shader_uid && vshaders[uid].frameCount == frameCount)
|
||||||
{
|
{
|
||||||
if (vshaders[uid].shader)
|
if (vshaders[uid].shader)
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
memcpy(&last_vertex_shader_uid, &uid, sizeof(VERTEXSHADERUID));
|
memcpy(&last_vertex_shader_uid, &uid, sizeof(VERTEXSHADERUID));
|
||||||
|
|
||||||
VSCache::iterator iter;
|
VSCache::iterator iter;
|
||||||
iter = vshaders.find(uid);
|
iter = vshaders.find(uid);
|
||||||
if (iter != vshaders.end())
|
if (iter != vshaders.end())
|
||||||
{
|
{
|
||||||
iter->second.frameCount = frameCount;
|
iter->second.frameCount = frameCount;
|
||||||
const VSCacheEntry &entry = iter->second;
|
const VSCacheEntry &entry = iter->second;
|
||||||
last_entry = &entry;
|
last_entry = &entry;
|
||||||
|
|
||||||
//DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true);
|
//DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true);
|
||||||
if (entry.shader)
|
if (entry.shader)
|
||||||
{
|
{
|
||||||
D3D::SetVertexShader(entry.shader);
|
D3D::SetVertexShader(entry.shader);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *code = GenerateVertexShaderCode(components, API_D3D9);
|
const char *code = GenerateVertexShaderCode(components, API_D3D9);
|
||||||
u8 *bytecode;
|
u8 *bytecode;
|
||||||
int bytecodelen;
|
int bytecodelen;
|
||||||
if (!D3D::CompileVertexShader(code, (int)strlen(code), &bytecode, &bytecodelen))
|
if (!D3D::CompileVertexShader(code, (int)strlen(code), &bytecode, &bytecodelen))
|
||||||
{
|
{
|
||||||
if (g_ActiveConfig.bShowShaderErrors)
|
if (g_ActiveConfig.bShowShaderErrors)
|
||||||
{
|
{
|
||||||
PanicAlert("Failed to compile Vertex Shader:\n\n%s", code);
|
PanicAlert("Failed to compile Vertex Shader:\n\n%s", code);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
g_vs_disk_cache.Append((u8 *)&uid, sizeof(uid), bytecode, bytecodelen);
|
g_vs_disk_cache.Append((u8 *)&uid, sizeof(uid), bytecode, bytecodelen);
|
||||||
g_vs_disk_cache.Sync();
|
g_vs_disk_cache.Sync();
|
||||||
|
|
||||||
bool result = InsertByteCode(uid, bytecode, bytecodelen, true);
|
bool result = InsertByteCode(uid, bytecode, bytecodelen, true);
|
||||||
delete [] bytecode;
|
delete [] bytecode;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VertexShaderCache::InsertByteCode(const VERTEXSHADERUID &uid, const u8 *bytecode, int bytecodelen, bool activate) {
|
bool VertexShaderCache::InsertByteCode(const VERTEXSHADERUID &uid, const u8 *bytecode, int bytecodelen, bool activate) {
|
||||||
LPDIRECT3DVERTEXSHADER9 shader = D3D::CreateVertexShaderFromByteCode(bytecode, bytecodelen);
|
LPDIRECT3DVERTEXSHADER9 shader = D3D::CreateVertexShaderFromByteCode(bytecode, bytecodelen);
|
||||||
|
|
||||||
// Make an entry in the table
|
// Make an entry in the table
|
||||||
VSCacheEntry entry;
|
VSCacheEntry entry;
|
||||||
entry.shader = shader;
|
entry.shader = shader;
|
||||||
entry.frameCount = frameCount;
|
entry.frameCount = frameCount;
|
||||||
|
|
||||||
vshaders[uid] = entry;
|
vshaders[uid] = entry;
|
||||||
last_entry = &vshaders[uid];
|
last_entry = &vshaders[uid];
|
||||||
if (!shader)
|
if (!shader)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
INCSTAT(stats.numVertexShadersCreated);
|
INCSTAT(stats.numVertexShadersCreated);
|
||||||
SETSTAT(stats.numVertexShadersAlive, (int)vshaders.size());
|
SETSTAT(stats.numVertexShadersAlive, (int)vshaders.size());
|
||||||
if (activate)
|
if (activate)
|
||||||
{
|
{
|
||||||
D3D::SetVertexShader(shader);
|
D3D::SetVertexShader(shader);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||||
std::string VertexShaderCache::GetCurrentShaderCode()
|
std::string VertexShaderCache::GetCurrentShaderCode()
|
||||||
{
|
{
|
||||||
return "(N/A)\n";
|
return "(N/A)\n";
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,81 +1,81 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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/
|
||||||
|
|
||||||
#ifndef _VERTEXSHADERCACHE_H
|
#ifndef _VERTEXSHADERCACHE_H
|
||||||
#define _VERTEXSHADERCACHE_H
|
#define _VERTEXSHADERCACHE_H
|
||||||
|
|
||||||
#include "DX9_D3DBase.h"
|
#include "DX9_D3DBase.h"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "DX9_D3DBase.h"
|
#include "DX9_D3DBase.h"
|
||||||
#include "VertexShaderGen.h"
|
#include "VertexShaderGen.h"
|
||||||
|
|
||||||
#include "../VertexShaderCache.h"
|
#include "../VertexShaderCache.h"
|
||||||
|
|
||||||
namespace DX9
|
namespace DX9
|
||||||
{
|
{
|
||||||
|
|
||||||
class VertexShaderCache : public ::VertexShaderCacheBase
|
class VertexShaderCache : public ::VertexShaderCacheBase
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
struct VSCacheEntry
|
struct VSCacheEntry
|
||||||
{
|
{
|
||||||
LPDIRECT3DVERTEXSHADER9 shader;
|
LPDIRECT3DVERTEXSHADER9 shader;
|
||||||
int frameCount;
|
int frameCount;
|
||||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||||
std::string code;
|
std::string code;
|
||||||
#endif
|
#endif
|
||||||
VSCacheEntry() : shader(NULL), frameCount(0) {}
|
VSCacheEntry() : shader(NULL), frameCount(0) {}
|
||||||
void Destroy()
|
void Destroy()
|
||||||
{
|
{
|
||||||
if (shader)
|
if (shader)
|
||||||
shader->Release();
|
shader->Release();
|
||||||
shader = NULL;
|
shader = NULL;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<VERTEXSHADERUID, VSCacheEntry> VSCache;
|
typedef std::map<VERTEXSHADERUID, VSCacheEntry> VSCache;
|
||||||
|
|
||||||
static VSCache vshaders;
|
static VSCache vshaders;
|
||||||
static const VSCacheEntry *last_entry;
|
static const VSCacheEntry *last_entry;
|
||||||
static void Clear();
|
static void Clear();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
VertexShaderCache();
|
VertexShaderCache();
|
||||||
~VertexShaderCache();
|
~VertexShaderCache();
|
||||||
|
|
||||||
void SetVSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4);
|
void SetVSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4);
|
||||||
void SetVSConstant4fv(unsigned int const_number, const float *f);
|
void SetVSConstant4fv(unsigned int const_number, const float *f);
|
||||||
void SetMultiVSConstant3fv(unsigned int const_number, unsigned int count, const float *f);
|
void SetMultiVSConstant3fv(unsigned int const_number, unsigned int count, const float *f);
|
||||||
void SetMultiVSConstant4fv(unsigned int const_number, unsigned int count, const float *f);
|
void SetMultiVSConstant4fv(unsigned int const_number, unsigned int count, const float *f);
|
||||||
|
|
||||||
bool SetShader(u32 components);
|
bool SetShader(u32 components);
|
||||||
|
|
||||||
static LPDIRECT3DVERTEXSHADER9 GetSimpleVertexShader(int level);
|
static LPDIRECT3DVERTEXSHADER9 GetSimpleVertexShader(int level);
|
||||||
static LPDIRECT3DVERTEXSHADER9 GetClearVertexShader();
|
static LPDIRECT3DVERTEXSHADER9 GetClearVertexShader();
|
||||||
static bool InsertByteCode(const VERTEXSHADERUID &uid, const u8 *bytecode, int bytecodelen, bool activate);
|
static bool InsertByteCode(const VERTEXSHADERUID &uid, const u8 *bytecode, int bytecodelen, bool activate);
|
||||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||||
static std::string GetCurrentShaderCode();
|
static std::string GetCurrentShaderCode();
|
||||||
#endif
|
#endif
|
||||||
static LPDIRECT3DVERTEXSHADER9 CompileCgShader(const char *pstrprogram);
|
static LPDIRECT3DVERTEXSHADER9 CompileCgShader(const char *pstrprogram);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // _VERTEXSHADERCACHE_H
|
#endif // _VERTEXSHADERCACHE_H
|
||||||
|
|||||||
@@ -1,233 +1,233 @@
|
|||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
// VideoCommon
|
// VideoCommon
|
||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
#include "Fifo.h"
|
#include "Fifo.h"
|
||||||
|
|
||||||
#include "EmuWindow.h"
|
#include "EmuWindow.h"
|
||||||
|
|
||||||
int OSDChoice = 0 , OSDTime = 0, OSDInternalW = 0, OSDInternalH = 0;
|
int OSDChoice = 0 , OSDTime = 0, OSDInternalW = 0, OSDInternalH = 0;
|
||||||
|
|
||||||
namespace EmuWindow
|
namespace EmuWindow
|
||||||
{
|
{
|
||||||
|
|
||||||
HWND m_hWnd = NULL;
|
HWND m_hWnd = NULL;
|
||||||
HWND m_hParent = NULL;
|
HWND m_hParent = NULL;
|
||||||
HINSTANCE m_hInstance = NULL;
|
HINSTANCE m_hInstance = NULL;
|
||||||
WNDCLASSEX wndClass;
|
WNDCLASSEX wndClass;
|
||||||
const TCHAR m_szClassName[] = _T("DolphinEmuWnd");
|
const TCHAR m_szClassName[] = _T("DolphinEmuWnd");
|
||||||
int g_winstyle;
|
int g_winstyle;
|
||||||
static volatile bool s_sizing;
|
static volatile bool s_sizing;
|
||||||
|
|
||||||
bool IsSizing()
|
bool IsSizing()
|
||||||
{
|
{
|
||||||
return s_sizing;
|
return s_sizing;
|
||||||
}
|
}
|
||||||
|
|
||||||
HWND GetWnd()
|
HWND GetWnd()
|
||||||
{
|
{
|
||||||
return m_hWnd;
|
return m_hWnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
HWND GetParentWnd()
|
HWND GetParentWnd()
|
||||||
{
|
{
|
||||||
return m_hParent;
|
return m_hParent;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
// KeyDown events
|
// KeyDown events
|
||||||
// -------------
|
// -------------
|
||||||
void OnKeyDown(WPARAM wParam)
|
void OnKeyDown(WPARAM wParam)
|
||||||
{
|
{
|
||||||
switch (LOWORD( wParam ))
|
switch (LOWORD( wParam ))
|
||||||
{
|
{
|
||||||
case '3': // OSD keys
|
case '3': // OSD keys
|
||||||
case '4':
|
case '4':
|
||||||
case '5':
|
case '5':
|
||||||
case '6':
|
case '6':
|
||||||
case '7':
|
case '7':
|
||||||
if (g_Config.bOSDHotKey)
|
if (g_Config.bOSDHotKey)
|
||||||
OSDMenu(wParam);
|
OSDMenu(wParam);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
LRESULT CALLBACK WndProc( HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam )
|
LRESULT CALLBACK WndProc( HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam )
|
||||||
{
|
{
|
||||||
switch( iMsg )
|
switch( iMsg )
|
||||||
{
|
{
|
||||||
case WM_PAINT:
|
case WM_PAINT:
|
||||||
{
|
{
|
||||||
HDC hdc;
|
HDC hdc;
|
||||||
PAINTSTRUCT ps;
|
PAINTSTRUCT ps;
|
||||||
hdc = BeginPaint(hWnd, &ps);
|
hdc = BeginPaint(hWnd, &ps);
|
||||||
EndPaint(hWnd, &ps);
|
EndPaint(hWnd, &ps);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_ENTERSIZEMOVE:
|
case WM_ENTERSIZEMOVE:
|
||||||
s_sizing = true;
|
s_sizing = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_EXITSIZEMOVE:
|
case WM_EXITSIZEMOVE:
|
||||||
s_sizing = false;
|
s_sizing = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Post thes mouse events to the main window, it's nessesary because in difference to the
|
/* Post thes mouse events to the main window, it's nessesary because in difference to the
|
||||||
keyboard inputs these events only appear here, not in the parent window or any other WndProc()*/
|
keyboard inputs these events only appear here, not in the parent window or any other WndProc()*/
|
||||||
case WM_LBUTTONDOWN:
|
case WM_LBUTTONDOWN:
|
||||||
case WM_LBUTTONUP:
|
case WM_LBUTTONUP:
|
||||||
case WM_LBUTTONDBLCLK:
|
case WM_LBUTTONDBLCLK:
|
||||||
PostMessage(GetParentWnd(), iMsg, wParam, lParam);
|
PostMessage(GetParentWnd(), iMsg, wParam, lParam);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_CLOSE:
|
case WM_CLOSE:
|
||||||
// When the user closes the window, we post an event to the main window to call Stop()
|
// When the user closes the window, we post an event to the main window to call Stop()
|
||||||
// Which then handles all the necessary steps to Shutdown the core + the plugins
|
// Which then handles all the necessary steps to Shutdown the core + the plugins
|
||||||
if (m_hParent == NULL)
|
if (m_hParent == NULL)
|
||||||
PostMessage(m_hParent, WM_USER, WM_USER_STOP, 0);
|
PostMessage(m_hParent, WM_USER, WM_USER_STOP, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_USER:
|
case WM_USER:
|
||||||
if (wParam == WM_USER_KEYDOWN)
|
if (wParam == WM_USER_KEYDOWN)
|
||||||
OnKeyDown(lParam);
|
OnKeyDown(lParam);
|
||||||
else if (wParam == WIIMOTE_DISCONNECT)
|
else if (wParam == WIIMOTE_DISCONNECT)
|
||||||
PostMessage(m_hParent, WM_USER, wParam, lParam);
|
PostMessage(m_hParent, WM_USER, wParam, lParam);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_SYSCOMMAND:
|
case WM_SYSCOMMAND:
|
||||||
switch (wParam)
|
switch (wParam)
|
||||||
{
|
{
|
||||||
case SC_SCREENSAVE:
|
case SC_SCREENSAVE:
|
||||||
case SC_MONITORPOWER:
|
case SC_MONITORPOWER:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return DefWindowProc(hWnd, iMsg, wParam, lParam);
|
return DefWindowProc(hWnd, iMsg, wParam, lParam);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_SETCURSOR:
|
case WM_SETCURSOR:
|
||||||
PostMessage(m_hParent, WM_USER, WM_USER_SETCURSOR, 0);
|
PostMessage(m_hParent, WM_USER, WM_USER_SETCURSOR, 0);
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return DefWindowProc(hWnd, iMsg, wParam, lParam);
|
return DefWindowProc(hWnd, iMsg, wParam, lParam);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
// OSD Menu
|
// OSD Menu
|
||||||
// -------------
|
// -------------
|
||||||
// Let's begin with 3 since 1 and 2 are default Wii keys
|
// Let's begin with 3 since 1 and 2 are default Wii keys
|
||||||
// -------------
|
// -------------
|
||||||
void OSDMenu(WPARAM wParam)
|
void OSDMenu(WPARAM wParam)
|
||||||
{
|
{
|
||||||
switch( LOWORD( wParam ))
|
switch( LOWORD( wParam ))
|
||||||
{
|
{
|
||||||
//case '3':
|
//case '3':
|
||||||
// OSDChoice = 1;
|
// OSDChoice = 1;
|
||||||
// // Toggle native resolution
|
// // Toggle native resolution
|
||||||
// OSDInternalW = D3D::GetBackBufferWidth();
|
// OSDInternalW = D3D::GetBackBufferWidth();
|
||||||
// OSDInternalH = D3D::GetBackBufferHeight();
|
// OSDInternalH = D3D::GetBackBufferHeight();
|
||||||
// break;
|
// break;
|
||||||
case '4':
|
case '4':
|
||||||
OSDChoice = 2;
|
OSDChoice = 2;
|
||||||
// Toggle aspect ratio
|
// Toggle aspect ratio
|
||||||
g_Config.iAspectRatio = (g_Config.iAspectRatio + 1) & 3;
|
g_Config.iAspectRatio = (g_Config.iAspectRatio + 1) & 3;
|
||||||
break;
|
break;
|
||||||
case '5':
|
case '5':
|
||||||
OSDChoice = 3;
|
OSDChoice = 3;
|
||||||
PanicAlert("Toggling EFB copy not implemented!\n");
|
PanicAlert("Toggling EFB copy not implemented!\n");
|
||||||
break;
|
break;
|
||||||
case '6':
|
case '6':
|
||||||
OSDChoice = 4;
|
OSDChoice = 4;
|
||||||
g_Config.bDisableFog = !g_Config.bDisableFog;
|
g_Config.bDisableFog = !g_Config.bDisableFog;
|
||||||
break;
|
break;
|
||||||
case '7':
|
case '7':
|
||||||
OSDChoice = 5;
|
OSDChoice = 5;
|
||||||
g_Config.bDisableLighting = !g_Config.bDisableLighting;
|
g_Config.bDisableLighting = !g_Config.bDisableLighting;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HWND OpenWindow(HWND parent, HINSTANCE hInstance, int width, int height, const TCHAR *title)
|
HWND OpenWindow(HWND parent, HINSTANCE hInstance, int width, int height, const TCHAR *title)
|
||||||
{
|
{
|
||||||
wndClass.cbSize = sizeof( wndClass );
|
wndClass.cbSize = sizeof( wndClass );
|
||||||
wndClass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
|
wndClass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
|
||||||
wndClass.lpfnWndProc = WndProc;
|
wndClass.lpfnWndProc = WndProc;
|
||||||
wndClass.cbClsExtra = 0;
|
wndClass.cbClsExtra = 0;
|
||||||
wndClass.cbWndExtra = 0;
|
wndClass.cbWndExtra = 0;
|
||||||
wndClass.hInstance = hInstance;
|
wndClass.hInstance = hInstance;
|
||||||
wndClass.hIcon = LoadIcon( NULL, IDI_APPLICATION );
|
wndClass.hIcon = LoadIcon( NULL, IDI_APPLICATION );
|
||||||
wndClass.hCursor = NULL;
|
wndClass.hCursor = NULL;
|
||||||
wndClass.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
|
wndClass.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
|
||||||
wndClass.lpszMenuName = NULL;
|
wndClass.lpszMenuName = NULL;
|
||||||
wndClass.lpszClassName = m_szClassName;
|
wndClass.lpszClassName = m_szClassName;
|
||||||
wndClass.hIconSm = LoadIcon( NULL, IDI_APPLICATION );
|
wndClass.hIconSm = LoadIcon( NULL, IDI_APPLICATION );
|
||||||
|
|
||||||
m_hInstance = hInstance;
|
m_hInstance = hInstance;
|
||||||
RegisterClassEx( &wndClass );
|
RegisterClassEx( &wndClass );
|
||||||
|
|
||||||
m_hParent = parent;
|
m_hParent = parent;
|
||||||
|
|
||||||
m_hWnd = CreateWindow(m_szClassName, title, WS_CHILD,
|
m_hWnd = CreateWindow(m_szClassName, title, WS_CHILD,
|
||||||
0, 0, width, height, m_hParent, NULL, hInstance, NULL);
|
0, 0, width, height, m_hParent, NULL, hInstance, NULL);
|
||||||
|
|
||||||
return m_hWnd;
|
return m_hWnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Show()
|
void Show()
|
||||||
{
|
{
|
||||||
ShowWindow(m_hWnd, SW_SHOW);
|
ShowWindow(m_hWnd, SW_SHOW);
|
||||||
BringWindowToTop(m_hWnd);
|
BringWindowToTop(m_hWnd);
|
||||||
UpdateWindow(m_hWnd);
|
UpdateWindow(m_hWnd);
|
||||||
SetFocus(m_hParent);
|
SetFocus(m_hParent);
|
||||||
}
|
}
|
||||||
|
|
||||||
HWND Create(HWND hParent, HINSTANCE hInstance, const TCHAR *title)
|
HWND Create(HWND hParent, HINSTANCE hInstance, const TCHAR *title)
|
||||||
{
|
{
|
||||||
// TODO:
|
// TODO:
|
||||||
// 1. Remove redundant window manipulation,
|
// 1. Remove redundant window manipulation,
|
||||||
// 2. Make DX11 in fullscreen can be overlapped by other dialogs
|
// 2. Make DX11 in fullscreen can be overlapped by other dialogs
|
||||||
// 3. Request window sizes which actually make the client area map to a common resolution
|
// 3. Request window sizes which actually make the client area map to a common resolution
|
||||||
HWND Ret;
|
HWND Ret;
|
||||||
int x=0, y=0, width=640, height=480;
|
int x=0, y=0, width=640, height=480;
|
||||||
g_VideoInitialize.pRequestWindowSize(x, y, width, height);
|
g_VideoInitialize.pRequestWindowSize(x, y, width, height);
|
||||||
|
|
||||||
Ret = OpenWindow(hParent, hInstance, width, height, title);
|
Ret = OpenWindow(hParent, hInstance, width, height, title);
|
||||||
|
|
||||||
if (Ret)
|
if (Ret)
|
||||||
{
|
{
|
||||||
Show();
|
Show();
|
||||||
}
|
}
|
||||||
return Ret;
|
return Ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Close()
|
void Close()
|
||||||
{
|
{
|
||||||
if (m_hParent == NULL)
|
if (m_hParent == NULL)
|
||||||
DestroyWindow(m_hWnd);
|
DestroyWindow(m_hWnd);
|
||||||
UnregisterClass(m_szClassName, m_hInstance);
|
UnregisterClass(m_szClassName, m_hInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetSize(int width, int height)
|
void SetSize(int width, int height)
|
||||||
{
|
{
|
||||||
RECT rc = {0, 0, width, height};
|
RECT rc = {0, 0, width, height};
|
||||||
DWORD style = GetWindowLong(m_hWnd, GWL_STYLE);
|
DWORD style = GetWindowLong(m_hWnd, GWL_STYLE);
|
||||||
AdjustWindowRect(&rc, style, false);
|
AdjustWindowRect(&rc, style, false);
|
||||||
|
|
||||||
int w = rc.right - rc.left;
|
int w = rc.right - rc.left;
|
||||||
int h = rc.bottom - rc.top;
|
int h = rc.bottom - rc.top;
|
||||||
|
|
||||||
rc.left = (1280 - w)/2;
|
rc.left = (1280 - w)/2;
|
||||||
rc.right = rc.left + w;
|
rc.right = rc.left + w;
|
||||||
rc.top = (1024 - h)/2;
|
rc.top = (1024 - h)/2;
|
||||||
rc.bottom = rc.top + h;
|
rc.bottom = rc.top + h;
|
||||||
MoveWindow(m_hWnd, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, TRUE);
|
MoveWindow(m_hWnd, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
|
|
||||||
#ifndef _EMUWINDOW_H_
|
#ifndef _EMUWINDOW_H_
|
||||||
#define _EMUWINDOW_H_
|
#define _EMUWINDOW_H_
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
namespace EmuWindow
|
namespace EmuWindow
|
||||||
{
|
{
|
||||||
|
|
||||||
HWND GetWnd();
|
HWND GetWnd();
|
||||||
HWND GetParentWnd();
|
HWND GetParentWnd();
|
||||||
HWND Create(HWND hParent, HINSTANCE hInstance, const TCHAR* title);
|
HWND Create(HWND hParent, HINSTANCE hInstance, const TCHAR* title);
|
||||||
void Show();
|
void Show();
|
||||||
void Close();
|
void Close();
|
||||||
void SetSize(int displayWidth, int displayHeight);
|
void SetSize(int displayWidth, int displayHeight);
|
||||||
bool IsSizing();
|
bool IsSizing();
|
||||||
void OSDMenu(WPARAM wParam);
|
void OSDMenu(WPARAM wParam);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,216 +1,216 @@
|
|||||||
|
|
||||||
#include "FramebufferManager.h"
|
#include "FramebufferManager.h"
|
||||||
|
|
||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
#include "Renderer.h"
|
#include "Renderer.h"
|
||||||
|
|
||||||
#include "Main.h"
|
#include "Main.h"
|
||||||
|
|
||||||
FramebufferManagerBase::VirtualXFBListType FramebufferManagerBase::m_virtualXFBList; // Only used in Virtual XFB mode
|
FramebufferManagerBase::VirtualXFBListType FramebufferManagerBase::m_virtualXFBList; // Only used in Virtual XFB mode
|
||||||
|
|
||||||
const XFBSourceBase* FramebufferManagerBase::m_overlappingXFBArray[];
|
const XFBSourceBase* FramebufferManagerBase::m_overlappingXFBArray[];
|
||||||
|
|
||||||
FramebufferManagerBase::~FramebufferManagerBase()
|
FramebufferManagerBase::~FramebufferManagerBase()
|
||||||
{
|
{
|
||||||
VirtualXFBListType::iterator
|
VirtualXFBListType::iterator
|
||||||
it = m_virtualXFBList.begin(),
|
it = m_virtualXFBList.begin(),
|
||||||
vlend = m_virtualXFBList.end();
|
vlend = m_virtualXFBList.end();
|
||||||
for (; it != vlend; ++it)
|
for (; it != vlend; ++it)
|
||||||
delete it->xfbSource;
|
delete it->xfbSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
const XFBSourceBase** FramebufferManagerBase::GetXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount)
|
const XFBSourceBase** FramebufferManagerBase::GetXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount)
|
||||||
{
|
{
|
||||||
//if (g_ActiveConfig.bUseRealXFB)
|
//if (g_ActiveConfig.bUseRealXFB)
|
||||||
// return getRealXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
|
// return getRealXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
|
||||||
//else
|
//else
|
||||||
return getVirtualXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
|
return getVirtualXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool addrRangesOverlap(u32 aLower, u32 aUpper, u32 bLower, u32 bUpper)
|
inline bool addrRangesOverlap(u32 aLower, u32 aUpper, u32 bLower, u32 bUpper)
|
||||||
{
|
{
|
||||||
return !((aLower >= bUpper) || (bLower >= aUpper));
|
return !((aLower >= bUpper) || (bLower >= aUpper));
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramebufferManagerBase::CopyToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
|
void FramebufferManagerBase::CopyToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
|
||||||
{
|
{
|
||||||
//if (g_ActiveConfig.bUseRealXFB)
|
//if (g_ActiveConfig.bUseRealXFB)
|
||||||
// copyToRealXFB(xfbAddr, fbWidth, fbHeight, sourceRc);
|
// copyToRealXFB(xfbAddr, fbWidth, fbHeight, sourceRc);
|
||||||
//else
|
//else
|
||||||
copyToVirtualXFB(xfbAddr, fbWidth, fbHeight, sourceRc);
|
copyToVirtualXFB(xfbAddr, fbWidth, fbHeight, sourceRc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramebufferManagerBase::replaceVirtualXFB()
|
void FramebufferManagerBase::replaceVirtualXFB()
|
||||||
{
|
{
|
||||||
VirtualXFBListType::iterator
|
VirtualXFBListType::iterator
|
||||||
it = m_virtualXFBList.begin(),
|
it = m_virtualXFBList.begin(),
|
||||||
vlend = m_virtualXFBList.end();
|
vlend = m_virtualXFBList.end();
|
||||||
|
|
||||||
VirtualXFB *vxfb = &*it;
|
VirtualXFB *vxfb = &*it;
|
||||||
|
|
||||||
const s32 srcLower = vxfb->xfbAddr;
|
const s32 srcLower = vxfb->xfbAddr;
|
||||||
const s32 srcUpper = vxfb->xfbAddr + 2 * vxfb->xfbWidth * vxfb->xfbHeight;
|
const s32 srcUpper = vxfb->xfbAddr + 2 * vxfb->xfbWidth * vxfb->xfbHeight;
|
||||||
const s32 lineSize = 2 * vxfb->xfbWidth;
|
const s32 lineSize = 2 * vxfb->xfbWidth;
|
||||||
|
|
||||||
while (++it != vlend)
|
while (++it != vlend)
|
||||||
{
|
{
|
||||||
vxfb = &*it;
|
vxfb = &*it;
|
||||||
|
|
||||||
const s32 dstLower = vxfb->xfbAddr;
|
const s32 dstLower = vxfb->xfbAddr;
|
||||||
const s32 dstUpper = vxfb->xfbAddr + 2 * vxfb->xfbWidth * vxfb->xfbHeight;
|
const s32 dstUpper = vxfb->xfbAddr + 2 * vxfb->xfbWidth * vxfb->xfbHeight;
|
||||||
|
|
||||||
if (dstLower >= srcLower && dstUpper <= srcUpper)
|
if (dstLower >= srcLower && dstUpper <= srcUpper)
|
||||||
{
|
{
|
||||||
// invalidate the data
|
// invalidate the data
|
||||||
vxfb->xfbAddr = 0;
|
vxfb->xfbAddr = 0;
|
||||||
vxfb->xfbHeight = 0;
|
vxfb->xfbHeight = 0;
|
||||||
vxfb->xfbWidth = 0;
|
vxfb->xfbWidth = 0;
|
||||||
}
|
}
|
||||||
else if (addrRangesOverlap(srcLower, srcUpper, dstLower, dstUpper))
|
else if (addrRangesOverlap(srcLower, srcUpper, dstLower, dstUpper))
|
||||||
{
|
{
|
||||||
const s32 upperOverlap = (srcUpper - dstLower) / lineSize;
|
const s32 upperOverlap = (srcUpper - dstLower) / lineSize;
|
||||||
const s32 lowerOverlap = (dstUpper - srcLower) / lineSize;
|
const s32 lowerOverlap = (dstUpper - srcLower) / lineSize;
|
||||||
|
|
||||||
if (upperOverlap > 0 && lowerOverlap < 0)
|
if (upperOverlap > 0 && lowerOverlap < 0)
|
||||||
{
|
{
|
||||||
vxfb->xfbAddr += lineSize * upperOverlap;
|
vxfb->xfbAddr += lineSize * upperOverlap;
|
||||||
vxfb->xfbHeight -= upperOverlap;
|
vxfb->xfbHeight -= upperOverlap;
|
||||||
}
|
}
|
||||||
else if (lowerOverlap > 0)
|
else if (lowerOverlap > 0)
|
||||||
{
|
{
|
||||||
vxfb->xfbHeight -= lowerOverlap;
|
vxfb->xfbHeight -= lowerOverlap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FramebufferManagerBase::VirtualXFBListType::iterator
|
FramebufferManagerBase::VirtualXFBListType::iterator
|
||||||
FramebufferManagerBase::findVirtualXFB(u32 xfbAddr, u32 width, u32 height)
|
FramebufferManagerBase::findVirtualXFB(u32 xfbAddr, u32 width, u32 height)
|
||||||
{
|
{
|
||||||
const u32 srcLower = xfbAddr;
|
const u32 srcLower = xfbAddr;
|
||||||
const u32 srcUpper = xfbAddr + 2 * width * height;
|
const u32 srcUpper = xfbAddr + 2 * width * height;
|
||||||
|
|
||||||
VirtualXFBListType::iterator
|
VirtualXFBListType::iterator
|
||||||
it = m_virtualXFBList.begin(),
|
it = m_virtualXFBList.begin(),
|
||||||
vlend = m_virtualXFBList.end();
|
vlend = m_virtualXFBList.end();
|
||||||
for (; it != vlend; ++it)
|
for (; it != vlend; ++it)
|
||||||
{
|
{
|
||||||
const VirtualXFB &vxfb = *it;
|
const VirtualXFB &vxfb = *it;
|
||||||
|
|
||||||
const u32 dstLower = vxfb.xfbAddr;
|
const u32 dstLower = vxfb.xfbAddr;
|
||||||
const u32 dstUpper = vxfb.xfbAddr + 2 * vxfb.xfbWidth * vxfb.xfbHeight;
|
const u32 dstUpper = vxfb.xfbAddr + 2 * vxfb.xfbWidth * vxfb.xfbHeight;
|
||||||
|
|
||||||
if (dstLower >= srcLower && dstUpper <= srcUpper)
|
if (dstLower >= srcLower && dstUpper <= srcUpper)
|
||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
|
|
||||||
// That address is not in the Virtual XFB list.
|
// That address is not in the Virtual XFB list.
|
||||||
return m_virtualXFBList.end();
|
return m_virtualXFBList.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramebufferManagerBase::copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
|
void FramebufferManagerBase::copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
|
||||||
{
|
{
|
||||||
const VirtualXFBListType::iterator it = findVirtualXFB(xfbAddr, fbWidth, fbHeight);
|
const VirtualXFBListType::iterator it = findVirtualXFB(xfbAddr, fbWidth, fbHeight);
|
||||||
|
|
||||||
VirtualXFB *vxfb = NULL;
|
VirtualXFB *vxfb = NULL;
|
||||||
|
|
||||||
if (m_virtualXFBList.end() == it)
|
if (m_virtualXFBList.end() == it)
|
||||||
{
|
{
|
||||||
if (m_virtualXFBList.size() >= MAX_VIRTUAL_XFB)
|
if (m_virtualXFBList.size() >= MAX_VIRTUAL_XFB)
|
||||||
{
|
{
|
||||||
PanicAlert("Requested creating a new virtual XFB although the maximum number has already been reached! Report this to the devs");
|
PanicAlert("Requested creating a new virtual XFB although the maximum number has already been reached! Report this to the devs");
|
||||||
return;
|
return;
|
||||||
// TODO, possible alternative to failing: just delete the oldest virtual XFB:
|
// TODO, possible alternative to failing: just delete the oldest virtual XFB:
|
||||||
// delete m_virtualXFBList.back().xfbSource;
|
// delete m_virtualXFBList.back().xfbSource;
|
||||||
// m_virtualXFBList.pop_back();
|
// m_virtualXFBList.pop_back();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// create a new Virtual XFB and place it at the front of the list
|
// create a new Virtual XFB and place it at the front of the list
|
||||||
VirtualXFB v;
|
VirtualXFB v;
|
||||||
m_virtualXFBList.push_front(v);
|
m_virtualXFBList.push_front(v);
|
||||||
vxfb = &m_virtualXFBList.front();
|
vxfb = &m_virtualXFBList.front();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vxfb = &*it;
|
vxfb = &*it;
|
||||||
delete vxfb->xfbSource;
|
delete vxfb->xfbSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
vxfb->xfbAddr = xfbAddr;
|
vxfb->xfbAddr = xfbAddr;
|
||||||
vxfb->xfbWidth = fbWidth;
|
vxfb->xfbWidth = fbWidth;
|
||||||
vxfb->xfbHeight = fbHeight;
|
vxfb->xfbHeight = fbHeight;
|
||||||
|
|
||||||
const float scaleX = RendererBase::GetXFBScaleX();
|
const float scaleX = RendererBase::GetXFBScaleX();
|
||||||
const float scaleY = RendererBase::GetXFBScaleY();
|
const float scaleY = RendererBase::GetXFBScaleY();
|
||||||
|
|
||||||
TargetRectangle targetSource;
|
TargetRectangle targetSource;
|
||||||
targetSource.top = (int)(sourceRc.top * scaleY);
|
targetSource.top = (int)(sourceRc.top * scaleY);
|
||||||
targetSource.bottom = (int)(sourceRc.bottom * scaleY);
|
targetSource.bottom = (int)(sourceRc.bottom * scaleY);
|
||||||
targetSource.left = (int)(sourceRc.left * scaleX);
|
targetSource.left = (int)(sourceRc.left * scaleX);
|
||||||
targetSource.right = (int)(sourceRc.right * scaleX);
|
targetSource.right = (int)(sourceRc.right * scaleX);
|
||||||
|
|
||||||
const unsigned int target_width = targetSource.right - targetSource.left;
|
const unsigned int target_width = targetSource.right - targetSource.left;
|
||||||
const unsigned int target_height = targetSource.bottom - targetSource.top;
|
const unsigned int target_height = targetSource.bottom - targetSource.top;
|
||||||
|
|
||||||
vxfb->xfbSource = g_framebuffer_manager->CreateXFBSource(target_width, target_height);
|
vxfb->xfbSource = g_framebuffer_manager->CreateXFBSource(target_width, target_height);
|
||||||
if (NULL == vxfb->xfbSource)
|
if (NULL == vxfb->xfbSource)
|
||||||
{
|
{
|
||||||
PanicAlert("Failed to create virtual XFB");
|
PanicAlert("Failed to create virtual XFB");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// why do both of these have a height/width/addr ?
|
// why do both of these have a height/width/addr ?
|
||||||
vxfb->xfbSource->srcAddr = xfbAddr;
|
vxfb->xfbSource->srcAddr = xfbAddr;
|
||||||
vxfb->xfbSource->srcWidth = fbWidth;
|
vxfb->xfbSource->srcWidth = fbWidth;
|
||||||
vxfb->xfbSource->srcHeight = fbHeight;
|
vxfb->xfbSource->srcHeight = fbHeight;
|
||||||
|
|
||||||
vxfb->xfbSource->texWidth = target_width;
|
vxfb->xfbSource->texWidth = target_width;
|
||||||
vxfb->xfbSource->texHeight = target_height;
|
vxfb->xfbSource->texHeight = target_height;
|
||||||
|
|
||||||
if (m_virtualXFBList.end() != it)
|
if (m_virtualXFBList.end() != it)
|
||||||
{
|
{
|
||||||
// move this Virtual XFB to the front of the list.
|
// move this Virtual XFB to the front of the list.
|
||||||
m_virtualXFBList.splice(m_virtualXFBList.begin(), m_virtualXFBList, it);
|
m_virtualXFBList.splice(m_virtualXFBList.begin(), m_virtualXFBList, it);
|
||||||
|
|
||||||
// keep stale XFB data from being used
|
// keep stale XFB data from being used
|
||||||
replaceVirtualXFB();
|
replaceVirtualXFB();
|
||||||
}
|
}
|
||||||
|
|
||||||
g_renderer->ResetAPIState(); // reset any game specific settings
|
g_renderer->ResetAPIState(); // reset any game specific settings
|
||||||
|
|
||||||
vxfb->xfbSource->CopyEFB(RendererBase::ConvertEFBRectangle(sourceRc));
|
vxfb->xfbSource->CopyEFB(RendererBase::ConvertEFBRectangle(sourceRc));
|
||||||
|
|
||||||
g_renderer->RestoreAPIState();
|
g_renderer->RestoreAPIState();
|
||||||
}
|
}
|
||||||
|
|
||||||
const XFBSourceBase** FramebufferManagerBase::getVirtualXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount)
|
const XFBSourceBase** FramebufferManagerBase::getVirtualXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount)
|
||||||
{
|
{
|
||||||
xfbCount = 0;
|
xfbCount = 0;
|
||||||
|
|
||||||
if (0 == m_virtualXFBList.size()) // no Virtual XFBs available
|
if (0 == m_virtualXFBList.size()) // no Virtual XFBs available
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
u32 srcLower = xfbAddr;
|
u32 srcLower = xfbAddr;
|
||||||
u32 srcUpper = xfbAddr + 2 * fbWidth * fbHeight;
|
u32 srcUpper = xfbAddr + 2 * fbWidth * fbHeight;
|
||||||
|
|
||||||
VirtualXFBListType::reverse_iterator
|
VirtualXFBListType::reverse_iterator
|
||||||
it = m_virtualXFBList.rbegin(),
|
it = m_virtualXFBList.rbegin(),
|
||||||
vlend = m_virtualXFBList.rend();
|
vlend = m_virtualXFBList.rend();
|
||||||
for (; it != vlend; ++it)
|
for (; it != vlend; ++it)
|
||||||
{
|
{
|
||||||
VirtualXFB* vxfb = &*it;
|
VirtualXFB* vxfb = &*it;
|
||||||
|
|
||||||
u32 dstLower = vxfb->xfbAddr;
|
u32 dstLower = vxfb->xfbAddr;
|
||||||
u32 dstUpper = vxfb->xfbAddr + 2 * vxfb->xfbWidth * vxfb->xfbHeight;
|
u32 dstUpper = vxfb->xfbAddr + 2 * vxfb->xfbWidth * vxfb->xfbHeight;
|
||||||
|
|
||||||
if (addrRangesOverlap(srcLower, srcUpper, dstLower, dstUpper))
|
if (addrRangesOverlap(srcLower, srcUpper, dstLower, dstUpper))
|
||||||
{
|
{
|
||||||
m_overlappingXFBArray[xfbCount] = vxfb->xfbSource;
|
m_overlappingXFBArray[xfbCount] = vxfb->xfbSource;
|
||||||
xfbCount++;
|
xfbCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &m_overlappingXFBArray[0];
|
return &m_overlappingXFBArray[0];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,71 +1,71 @@
|
|||||||
|
|
||||||
#ifndef _FRAMEBUFFERMANAGER_H_
|
#ifndef _FRAMEBUFFERMANAGER_H_
|
||||||
#define _FRAMEBUFFERMANAGER_H_
|
#define _FRAMEBUFFERMANAGER_H_
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
#include "CommonTypes.h"
|
#include "CommonTypes.h"
|
||||||
#include "VideoCommon.h"
|
#include "VideoCommon.h"
|
||||||
|
|
||||||
struct XFBSourceBase
|
struct XFBSourceBase
|
||||||
{
|
{
|
||||||
u32 srcAddr;
|
u32 srcAddr;
|
||||||
u32 srcWidth;
|
u32 srcWidth;
|
||||||
u32 srcHeight;
|
u32 srcHeight;
|
||||||
|
|
||||||
unsigned int texWidth;
|
unsigned int texWidth;
|
||||||
unsigned int texHeight;
|
unsigned int texHeight;
|
||||||
|
|
||||||
virtual void CopyEFB(const TargetRectangle& efbSource) = 0;
|
virtual void CopyEFB(const TargetRectangle& efbSource) = 0;
|
||||||
|
|
||||||
virtual ~XFBSourceBase() {}
|
virtual ~XFBSourceBase() {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
XFBSourceBase() : srcAddr(0), srcWidth(0), srcHeight(0), texWidth(0), texHeight(0) {}
|
XFBSourceBase() : srcAddr(0), srcWidth(0), srcHeight(0), texWidth(0), texHeight(0) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class FramebufferManagerBase
|
class FramebufferManagerBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
MAX_VIRTUAL_XFB = 8,
|
MAX_VIRTUAL_XFB = 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual ~FramebufferManagerBase();
|
virtual ~FramebufferManagerBase();
|
||||||
|
|
||||||
//virtual void Init(int targetWidth, int targetHeight, int msaaSamples, int msaaCoverageSamples) = 0;
|
//virtual void Init(int targetWidth, int targetHeight, int msaaSamples, int msaaCoverageSamples) = 0;
|
||||||
//virtual void Shutdown() = 0;
|
//virtual void Shutdown() = 0;
|
||||||
|
|
||||||
static void replaceVirtualXFB();
|
static void replaceVirtualXFB();
|
||||||
|
|
||||||
static void CopyToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc);
|
static void CopyToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc);
|
||||||
|
|
||||||
static const XFBSourceBase** GetXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount);
|
static const XFBSourceBase** GetXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount);
|
||||||
static const XFBSourceBase** getVirtualXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount);
|
static const XFBSourceBase** getVirtualXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount);
|
||||||
|
|
||||||
//protected:
|
//protected:
|
||||||
struct VirtualXFB
|
struct VirtualXFB
|
||||||
{
|
{
|
||||||
// Address and size in GameCube RAM
|
// Address and size in GameCube RAM
|
||||||
u32 xfbAddr;
|
u32 xfbAddr;
|
||||||
u32 xfbWidth;
|
u32 xfbWidth;
|
||||||
u32 xfbHeight;
|
u32 xfbHeight;
|
||||||
|
|
||||||
XFBSourceBase *xfbSource;
|
XFBSourceBase *xfbSource;
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual XFBSourceBase* CreateXFBSource(unsigned int target_width, unsigned int target_height) = 0;
|
virtual XFBSourceBase* CreateXFBSource(unsigned int target_width, unsigned int target_height) = 0;
|
||||||
|
|
||||||
typedef std::list<VirtualXFB> VirtualXFBListType;
|
typedef std::list<VirtualXFB> VirtualXFBListType;
|
||||||
static VirtualXFBListType m_virtualXFBList; // used in virtual XFB mode
|
static VirtualXFBListType m_virtualXFBList; // used in virtual XFB mode
|
||||||
|
|
||||||
static VirtualXFBListType::iterator findVirtualXFB(u32 xfbAddr, u32 width, u32 height);
|
static VirtualXFBListType::iterator findVirtualXFB(u32 xfbAddr, u32 width, u32 height);
|
||||||
|
|
||||||
static void copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc);
|
static void copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc);
|
||||||
|
|
||||||
static const XFBSourceBase* m_overlappingXFBArray[MAX_VIRTUAL_XFB];
|
static const XFBSourceBase* m_overlappingXFBArray[MAX_VIRTUAL_XFB];
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,57 +1,57 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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/
|
||||||
|
|
||||||
#ifndef _MAIN_H_
|
#ifndef _MAIN_H_
|
||||||
#define _MAIN_H_
|
#define _MAIN_H_
|
||||||
|
|
||||||
#include "PluginSpecs_Video.h"
|
#include "PluginSpecs_Video.h"
|
||||||
|
|
||||||
#include "Renderer.h"
|
#include "Renderer.h"
|
||||||
#include "TextureCache.h"
|
#include "TextureCache.h"
|
||||||
#include "VertexManager.h"
|
#include "VertexManager.h"
|
||||||
#include "PixelShaderCache.h"
|
#include "PixelShaderCache.h"
|
||||||
#include "VertexShaderCache.h"
|
#include "VertexShaderCache.h"
|
||||||
#include "FramebufferManager.h"
|
#include "FramebufferManager.h"
|
||||||
|
|
||||||
extern SVideoInitialize g_VideoInitialize;
|
extern SVideoInitialize g_VideoInitialize;
|
||||||
extern volatile u32 s_swapRequested;
|
extern volatile u32 s_swapRequested;
|
||||||
extern PLUGIN_GLOBALS *g_globals;
|
extern PLUGIN_GLOBALS *g_globals;
|
||||||
|
|
||||||
extern RendererBase *g_renderer;
|
extern RendererBase *g_renderer;
|
||||||
extern TextureCacheBase *g_texture_cache;
|
extern TextureCacheBase *g_texture_cache;
|
||||||
extern VertexManagerBase *g_vertex_manager;
|
extern VertexManagerBase *g_vertex_manager;
|
||||||
extern VertexShaderCacheBase* g_vertex_shader_cache;
|
extern VertexShaderCacheBase* g_vertex_shader_cache;
|
||||||
extern PixelShaderCacheBase* g_pixel_shader_cache;
|
extern PixelShaderCacheBase* g_pixel_shader_cache;
|
||||||
extern FramebufferManagerBase* g_framebuffer_manager;
|
extern FramebufferManagerBase* g_framebuffer_manager;
|
||||||
|
|
||||||
extern int frameCount;
|
extern int frameCount;
|
||||||
|
|
||||||
void VideoFifo_CheckEFBAccess();
|
void VideoFifo_CheckEFBAccess();
|
||||||
void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight);
|
void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight);
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
GFXAPI_SOFTWARE,
|
GFXAPI_SOFTWARE,
|
||||||
GFXAPI_OPENGL,
|
GFXAPI_OPENGL,
|
||||||
GFXAPI_D3D9,
|
GFXAPI_D3D9,
|
||||||
GFXAPI_D3D11,
|
GFXAPI_D3D11,
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const char* const g_gfxapi_names[];
|
extern const char* const g_gfxapi_names[];
|
||||||
extern int g_gfxapi;
|
extern int g_gfxapi;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,385 +1,385 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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/
|
||||||
|
|
||||||
// OGL
|
// OGL
|
||||||
#include "OGL_Render.h"
|
#include "OGL_Render.h"
|
||||||
#include "OGL_XFB.h"
|
#include "OGL_XFB.h"
|
||||||
#include "OGL_FramebufferManager.h"
|
#include "OGL_FramebufferManager.h"
|
||||||
#include "OGL_TextureConverter.h"
|
#include "OGL_TextureConverter.h"
|
||||||
|
|
||||||
namespace OGL
|
namespace OGL
|
||||||
{
|
{
|
||||||
|
|
||||||
extern bool s_bHaveFramebufferBlit; // comes from Render.cpp
|
extern bool s_bHaveFramebufferBlit; // comes from Render.cpp
|
||||||
|
|
||||||
int FramebufferManager::m_targetWidth;
|
int FramebufferManager::m_targetWidth;
|
||||||
int FramebufferManager::m_targetHeight;
|
int FramebufferManager::m_targetHeight;
|
||||||
int FramebufferManager::m_msaaSamples;
|
int FramebufferManager::m_msaaSamples;
|
||||||
int FramebufferManager::m_msaaCoverageSamples;
|
int FramebufferManager::m_msaaCoverageSamples;
|
||||||
|
|
||||||
GLuint FramebufferManager::m_efbFramebuffer;
|
GLuint FramebufferManager::m_efbFramebuffer;
|
||||||
GLuint FramebufferManager::m_efbColor; // Renderbuffer in MSAA mode; Texture otherwise
|
GLuint FramebufferManager::m_efbColor; // Renderbuffer in MSAA mode; Texture otherwise
|
||||||
GLuint FramebufferManager::m_efbDepth; // Renderbuffer in MSAA mode; Texture otherwise
|
GLuint FramebufferManager::m_efbDepth; // Renderbuffer in MSAA mode; Texture otherwise
|
||||||
|
|
||||||
// Only used in MSAA mode.
|
// Only used in MSAA mode.
|
||||||
GLuint FramebufferManager::m_resolvedFramebuffer;
|
GLuint FramebufferManager::m_resolvedFramebuffer;
|
||||||
GLuint FramebufferManager::m_resolvedColorTexture;
|
GLuint FramebufferManager::m_resolvedColorTexture;
|
||||||
GLuint FramebufferManager::m_resolvedDepthTexture;
|
GLuint FramebufferManager::m_resolvedDepthTexture;
|
||||||
|
|
||||||
GLuint FramebufferManager::m_xfbFramebuffer; // Only used in MSAA mode
|
GLuint FramebufferManager::m_xfbFramebuffer; // Only used in MSAA mode
|
||||||
XFBSource FramebufferManager::m_realXFBSource; // Only used in Real XFB mode
|
XFBSource FramebufferManager::m_realXFBSource; // Only used in Real XFB mode
|
||||||
|
|
||||||
FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int msaaSamples, int msaaCoverageSamples)
|
FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int msaaSamples, int msaaCoverageSamples)
|
||||||
{
|
{
|
||||||
// m_efbFramebuffer(0),
|
// m_efbFramebuffer(0),
|
||||||
// m_efbColor(0),
|
// m_efbColor(0),
|
||||||
// m_efbDepth(0),
|
// m_efbDepth(0),
|
||||||
// m_resolvedFramebuffer(0),
|
// m_resolvedFramebuffer(0),
|
||||||
// m_resolvedColorTexture(0),
|
// m_resolvedColorTexture(0),
|
||||||
// m_resolvedDepthTexture(0),
|
// m_resolvedDepthTexture(0),
|
||||||
// m_xfbFramebuffer(0)
|
// m_xfbFramebuffer(0)
|
||||||
|
|
||||||
m_targetWidth = targetWidth;
|
m_targetWidth = targetWidth;
|
||||||
m_targetHeight = targetHeight;
|
m_targetHeight = targetHeight;
|
||||||
m_msaaSamples = msaaSamples;
|
m_msaaSamples = msaaSamples;
|
||||||
m_msaaCoverageSamples = msaaCoverageSamples;
|
m_msaaCoverageSamples = msaaCoverageSamples;
|
||||||
|
|
||||||
// The EFB can be set to different pixel formats by the game through the
|
// The EFB can be set to different pixel formats by the game through the
|
||||||
// BPMEM_ZCOMPARE register (which should probably have a different name).
|
// BPMEM_ZCOMPARE register (which should probably have a different name).
|
||||||
// They are:
|
// They are:
|
||||||
// - 24-bit RGB (8-bit components) with 24-bit Z
|
// - 24-bit RGB (8-bit components) with 24-bit Z
|
||||||
// - 24-bit RGBA (6-bit components) with 24-bit Z
|
// - 24-bit RGBA (6-bit components) with 24-bit Z
|
||||||
// - Multisampled 16-bit RGB (5-6-5 format) with 16-bit Z
|
// - Multisampled 16-bit RGB (5-6-5 format) with 16-bit Z
|
||||||
// We only use one EFB format here: 32-bit ARGB with 24-bit Z.
|
// We only use one EFB format here: 32-bit ARGB with 24-bit Z.
|
||||||
// Multisampling depends on user settings.
|
// Multisampling depends on user settings.
|
||||||
// The distinction becomes important for certain operations, i.e. the
|
// The distinction becomes important for certain operations, i.e. the
|
||||||
// alpha channel should be ignored if the EFB does not have one.
|
// alpha channel should be ignored if the EFB does not have one.
|
||||||
|
|
||||||
// Create EFB target.
|
// Create EFB target.
|
||||||
|
|
||||||
glGenFramebuffersEXT(1, &m_efbFramebuffer);
|
glGenFramebuffersEXT(1, &m_efbFramebuffer);
|
||||||
|
|
||||||
if (m_msaaSamples <= 1)
|
if (m_msaaSamples <= 1)
|
||||||
{
|
{
|
||||||
// EFB targets will be textures in non-MSAA mode.
|
// EFB targets will be textures in non-MSAA mode.
|
||||||
|
|
||||||
GLuint glObj[2];
|
GLuint glObj[2];
|
||||||
glGenTextures(2, glObj);
|
glGenTextures(2, glObj);
|
||||||
m_efbColor = glObj[0];
|
m_efbColor = glObj[0];
|
||||||
m_efbDepth = glObj[1];
|
m_efbDepth = glObj[1];
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_efbColor);
|
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_efbColor);
|
||||||
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, m_targetWidth, m_targetHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, m_targetWidth, m_targetHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_efbDepth);
|
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_efbDepth);
|
||||||
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
|
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
|
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
|
||||||
|
|
||||||
// Bind target textures to the EFB framebuffer.
|
// Bind target textures to the EFB framebuffer.
|
||||||
|
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer);
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer);
|
||||||
|
|
||||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, m_efbColor, 0);
|
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, m_efbColor, 0);
|
||||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_RECTANGLE_ARB, m_efbDepth, 0);
|
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_RECTANGLE_ARB, m_efbDepth, 0);
|
||||||
|
|
||||||
GL_REPORT_FBO_ERROR();
|
GL_REPORT_FBO_ERROR();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// EFB targets will be renderbuffers in MSAA mode (required by OpenGL).
|
// EFB targets will be renderbuffers in MSAA mode (required by OpenGL).
|
||||||
// Resolve targets will be created to transfer EFB to RAM textures.
|
// Resolve targets will be created to transfer EFB to RAM textures.
|
||||||
// XFB framebuffer will be created to transfer EFB to XFB texture.
|
// XFB framebuffer will be created to transfer EFB to XFB texture.
|
||||||
|
|
||||||
// Create EFB target renderbuffers.
|
// Create EFB target renderbuffers.
|
||||||
|
|
||||||
GLuint glObj[2];
|
GLuint glObj[2];
|
||||||
glGenRenderbuffersEXT(2, glObj);
|
glGenRenderbuffersEXT(2, glObj);
|
||||||
m_efbColor = glObj[0];
|
m_efbColor = glObj[0];
|
||||||
m_efbDepth = glObj[1];
|
m_efbDepth = glObj[1];
|
||||||
|
|
||||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_efbColor);
|
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_efbColor);
|
||||||
if (m_msaaCoverageSamples)
|
if (m_msaaCoverageSamples)
|
||||||
glRenderbufferStorageMultisampleCoverageNV(GL_RENDERBUFFER_EXT, m_msaaCoverageSamples, m_msaaSamples, GL_RGBA8, m_targetWidth, m_targetHeight);
|
glRenderbufferStorageMultisampleCoverageNV(GL_RENDERBUFFER_EXT, m_msaaCoverageSamples, m_msaaSamples, GL_RGBA8, m_targetWidth, m_targetHeight);
|
||||||
else
|
else
|
||||||
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, m_msaaSamples, GL_RGBA8, m_targetWidth, m_targetHeight);
|
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, m_msaaSamples, GL_RGBA8, m_targetWidth, m_targetHeight);
|
||||||
|
|
||||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_efbDepth);
|
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_efbDepth);
|
||||||
if (m_msaaCoverageSamples)
|
if (m_msaaCoverageSamples)
|
||||||
glRenderbufferStorageMultisampleCoverageNV(GL_RENDERBUFFER_EXT, m_msaaCoverageSamples, m_msaaSamples, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight);
|
glRenderbufferStorageMultisampleCoverageNV(GL_RENDERBUFFER_EXT, m_msaaCoverageSamples, m_msaaSamples, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight);
|
||||||
else
|
else
|
||||||
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, m_msaaSamples, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight);
|
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, m_msaaSamples, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight);
|
||||||
|
|
||||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
|
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
|
||||||
|
|
||||||
// Bind target renderbuffers to EFB framebuffer.
|
// Bind target renderbuffers to EFB framebuffer.
|
||||||
|
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer);
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer);
|
||||||
|
|
||||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_efbColor);
|
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_efbColor);
|
||||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_efbDepth);
|
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_efbDepth);
|
||||||
|
|
||||||
GL_REPORT_FBO_ERROR();
|
GL_REPORT_FBO_ERROR();
|
||||||
|
|
||||||
// Create resolved targets for transferring multisampled EFB to texture.
|
// Create resolved targets for transferring multisampled EFB to texture.
|
||||||
|
|
||||||
glGenFramebuffersEXT(1, &m_resolvedFramebuffer);
|
glGenFramebuffersEXT(1, &m_resolvedFramebuffer);
|
||||||
|
|
||||||
glGenTextures(2, glObj);
|
glGenTextures(2, glObj);
|
||||||
m_resolvedColorTexture = glObj[0];
|
m_resolvedColorTexture = glObj[0];
|
||||||
m_resolvedDepthTexture = glObj[1];
|
m_resolvedDepthTexture = glObj[1];
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_resolvedColorTexture);
|
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_resolvedColorTexture);
|
||||||
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, m_targetWidth, m_targetHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, m_targetWidth, m_targetHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_resolvedDepthTexture);
|
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_resolvedDepthTexture);
|
||||||
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
|
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
|
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
|
||||||
|
|
||||||
// Bind resolved textures to resolved framebuffer.
|
// Bind resolved textures to resolved framebuffer.
|
||||||
|
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_resolvedFramebuffer);
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_resolvedFramebuffer);
|
||||||
|
|
||||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, m_resolvedColorTexture, 0);
|
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, m_resolvedColorTexture, 0);
|
||||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_RECTANGLE_ARB, m_resolvedDepthTexture, 0);
|
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_RECTANGLE_ARB, m_resolvedDepthTexture, 0);
|
||||||
|
|
||||||
GL_REPORT_FBO_ERROR();
|
GL_REPORT_FBO_ERROR();
|
||||||
|
|
||||||
// Return to EFB framebuffer.
|
// Return to EFB framebuffer.
|
||||||
|
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer);
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create XFB framebuffer; targets will be created elsewhere.
|
// Create XFB framebuffer; targets will be created elsewhere.
|
||||||
|
|
||||||
glGenFramebuffersEXT(1, &m_xfbFramebuffer);
|
glGenFramebuffersEXT(1, &m_xfbFramebuffer);
|
||||||
|
|
||||||
// EFB framebuffer is currently bound.
|
// EFB framebuffer is currently bound.
|
||||||
}
|
}
|
||||||
|
|
||||||
FramebufferManager::~FramebufferManager()
|
FramebufferManager::~FramebufferManager()
|
||||||
{
|
{
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||||
|
|
||||||
GLuint glObj[3];
|
GLuint glObj[3];
|
||||||
|
|
||||||
// Note: OpenGL deletion functions silently ignore parameters of "0".
|
// Note: OpenGL deletion functions silently ignore parameters of "0".
|
||||||
|
|
||||||
glObj[0] = m_efbFramebuffer;
|
glObj[0] = m_efbFramebuffer;
|
||||||
glObj[1] = m_resolvedFramebuffer;
|
glObj[1] = m_resolvedFramebuffer;
|
||||||
glObj[2] = m_xfbFramebuffer;
|
glObj[2] = m_xfbFramebuffer;
|
||||||
glDeleteFramebuffersEXT(3, glObj);
|
glDeleteFramebuffersEXT(3, glObj);
|
||||||
m_efbFramebuffer = 0;
|
m_efbFramebuffer = 0;
|
||||||
m_xfbFramebuffer = 0;
|
m_xfbFramebuffer = 0;
|
||||||
|
|
||||||
glObj[0] = m_resolvedColorTexture;
|
glObj[0] = m_resolvedColorTexture;
|
||||||
glObj[1] = m_resolvedDepthTexture;
|
glObj[1] = m_resolvedDepthTexture;
|
||||||
glObj[2] = m_realXFBSource.texture;
|
glObj[2] = m_realXFBSource.texture;
|
||||||
glDeleteTextures(3, glObj);
|
glDeleteTextures(3, glObj);
|
||||||
m_resolvedColorTexture = 0;
|
m_resolvedColorTexture = 0;
|
||||||
m_resolvedDepthTexture = 0;
|
m_resolvedDepthTexture = 0;
|
||||||
m_realXFBSource.texture = 0;
|
m_realXFBSource.texture = 0;
|
||||||
|
|
||||||
glObj[0] = m_efbColor;
|
glObj[0] = m_efbColor;
|
||||||
glObj[1] = m_efbDepth;
|
glObj[1] = m_efbDepth;
|
||||||
if (m_msaaSamples <= 1)
|
if (m_msaaSamples <= 1)
|
||||||
glDeleteTextures(2, glObj);
|
glDeleteTextures(2, glObj);
|
||||||
else
|
else
|
||||||
glDeleteRenderbuffersEXT(2, glObj);
|
glDeleteRenderbuffersEXT(2, glObj);
|
||||||
m_efbColor = 0;
|
m_efbColor = 0;
|
||||||
m_efbDepth = 0;
|
m_efbDepth = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
XFBSourceBase* FramebufferManager::CreateXFBSource(unsigned int target_width, unsigned int target_height)
|
XFBSourceBase* FramebufferManager::CreateXFBSource(unsigned int target_width, unsigned int target_height)
|
||||||
{
|
{
|
||||||
XFBSource* const xfbs = new XFBSource;
|
XFBSource* const xfbs = new XFBSource;
|
||||||
|
|
||||||
glGenTextures(1, &xfbs->texture);
|
glGenTextures(1, &xfbs->texture);
|
||||||
|
|
||||||
return xfbs;
|
return xfbs;
|
||||||
}
|
}
|
||||||
|
|
||||||
void XFBSource::CopyEFB(const TargetRectangle& efbSource)
|
void XFBSource::CopyEFB(const TargetRectangle& efbSource)
|
||||||
{
|
{
|
||||||
// Copy EFB to XFB texture
|
// Copy EFB to XFB texture
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (m_msaaSamples <= 1)
|
if (m_msaaSamples <= 1)
|
||||||
#else
|
#else
|
||||||
if (!s_bHaveFramebufferBlit)
|
if (!s_bHaveFramebufferBlit)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
// Just copy the EFB directly.
|
// Just copy the EFB directly.
|
||||||
|
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FramebufferManager::m_efbFramebuffer);
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FramebufferManager::m_efbFramebuffer);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture);
|
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture);
|
||||||
glCopyTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, 0, 0, texWidth, texHeight, 0);
|
glCopyTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, 0, 0, texWidth, texHeight, 0);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
|
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// OpenGL cannot copy directly from a multisampled framebuffer, so use
|
// OpenGL cannot copy directly from a multisampled framebuffer, so use
|
||||||
// EXT_framebuffer_blit.
|
// EXT_framebuffer_blit.
|
||||||
|
|
||||||
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, FramebufferManager::m_efbFramebuffer);
|
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, FramebufferManager::m_efbFramebuffer);
|
||||||
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, FramebufferManager::m_xfbFramebuffer);
|
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, FramebufferManager::m_xfbFramebuffer);
|
||||||
|
|
||||||
// Bind texture.
|
// Bind texture.
|
||||||
glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
|
glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
|
||||||
GL_TEXTURE_RECTANGLE_ARB, texture, 0);
|
GL_TEXTURE_RECTANGLE_ARB, texture, 0);
|
||||||
|
|
||||||
GL_REPORT_FBO_ERROR();
|
GL_REPORT_FBO_ERROR();
|
||||||
|
|
||||||
glBlitFramebufferEXT(0, 0, texWidth, texHeight, 0, 0, texWidth,
|
glBlitFramebufferEXT(0, 0, texWidth, texHeight, 0, 0, texWidth,
|
||||||
texHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
texHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||||
|
|
||||||
// Unbind texture.
|
// Unbind texture.
|
||||||
glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, 0, 0);
|
glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, 0, 0);
|
||||||
|
|
||||||
// Return to EFB.
|
// Return to EFB.
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FramebufferManager::m_efbFramebuffer);
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FramebufferManager::m_efbFramebuffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint FramebufferManager::GetEFBColorTexture(const EFBRectangle& sourceRc)
|
GLuint FramebufferManager::GetEFBColorTexture(const EFBRectangle& sourceRc)
|
||||||
{
|
{
|
||||||
if (m_msaaSamples <= 1)
|
if (m_msaaSamples <= 1)
|
||||||
{
|
{
|
||||||
return m_efbColor;
|
return m_efbColor;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Transfer the EFB to a resolved texture. EXT_framebuffer_blit is
|
// Transfer the EFB to a resolved texture. EXT_framebuffer_blit is
|
||||||
// required.
|
// required.
|
||||||
|
|
||||||
TargetRectangle targetRc = RendererBase::ConvertEFBRectangle(sourceRc);
|
TargetRectangle targetRc = RendererBase::ConvertEFBRectangle(sourceRc);
|
||||||
targetRc.ClampLL(0, 0, m_targetWidth, m_targetHeight);
|
targetRc.ClampLL(0, 0, m_targetWidth, m_targetHeight);
|
||||||
|
|
||||||
// Resolve.
|
// Resolve.
|
||||||
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_efbFramebuffer);
|
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_efbFramebuffer);
|
||||||
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_resolvedFramebuffer);
|
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_resolvedFramebuffer);
|
||||||
glBlitFramebufferEXT(
|
glBlitFramebufferEXT(
|
||||||
targetRc.left, targetRc.top, targetRc.right, targetRc.bottom,
|
targetRc.left, targetRc.top, targetRc.right, targetRc.bottom,
|
||||||
targetRc.left, targetRc.top, targetRc.right, targetRc.bottom,
|
targetRc.left, targetRc.top, targetRc.right, targetRc.bottom,
|
||||||
GL_COLOR_BUFFER_BIT, GL_NEAREST
|
GL_COLOR_BUFFER_BIT, GL_NEAREST
|
||||||
);
|
);
|
||||||
|
|
||||||
// Return to EFB.
|
// Return to EFB.
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer);
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer);
|
||||||
|
|
||||||
return m_resolvedColorTexture;
|
return m_resolvedColorTexture;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint FramebufferManager::GetEFBDepthTexture(const EFBRectangle& sourceRc)
|
GLuint FramebufferManager::GetEFBDepthTexture(const EFBRectangle& sourceRc)
|
||||||
{
|
{
|
||||||
if (m_msaaSamples <= 1)
|
if (m_msaaSamples <= 1)
|
||||||
{
|
{
|
||||||
return m_efbDepth;
|
return m_efbDepth;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Transfer the EFB to a resolved texture. EXT_framebuffer_blit is
|
// Transfer the EFB to a resolved texture. EXT_framebuffer_blit is
|
||||||
// required.
|
// required.
|
||||||
|
|
||||||
TargetRectangle targetRc = RendererBase::ConvertEFBRectangle(sourceRc);
|
TargetRectangle targetRc = RendererBase::ConvertEFBRectangle(sourceRc);
|
||||||
targetRc.ClampLL(0, 0, m_targetWidth, m_targetHeight);
|
targetRc.ClampLL(0, 0, m_targetWidth, m_targetHeight);
|
||||||
|
|
||||||
// Resolve.
|
// Resolve.
|
||||||
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_efbFramebuffer);
|
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_efbFramebuffer);
|
||||||
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_resolvedFramebuffer);
|
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_resolvedFramebuffer);
|
||||||
glBlitFramebufferEXT(
|
glBlitFramebufferEXT(
|
||||||
targetRc.left, targetRc.top, targetRc.right, targetRc.bottom,
|
targetRc.left, targetRc.top, targetRc.right, targetRc.bottom,
|
||||||
targetRc.left, targetRc.top, targetRc.right, targetRc.bottom,
|
targetRc.left, targetRc.top, targetRc.right, targetRc.bottom,
|
||||||
GL_DEPTH_BUFFER_BIT, GL_NEAREST
|
GL_DEPTH_BUFFER_BIT, GL_NEAREST
|
||||||
);
|
);
|
||||||
|
|
||||||
// Return to EFB.
|
// Return to EFB.
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer);
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer);
|
||||||
|
|
||||||
return m_resolvedDepthTexture;
|
return m_resolvedDepthTexture;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramebufferManager::copyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
|
void FramebufferManager::copyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
|
||||||
{
|
{
|
||||||
u8* pXFB = Memory_GetPtr(xfbAddr);
|
u8* pXFB = Memory_GetPtr(xfbAddr);
|
||||||
if (!pXFB)
|
if (!pXFB)
|
||||||
{
|
{
|
||||||
WARN_LOG(VIDEO, "Tried to copy to invalid XFB address");
|
WARN_LOG(VIDEO, "Tried to copy to invalid XFB address");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
XFB_Write(pXFB, sourceRc, fbWidth, fbHeight);
|
XFB_Write(pXFB, sourceRc, fbWidth, fbHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
const XFBSourceBase** FramebufferManager::getRealXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount)
|
const XFBSourceBase** FramebufferManager::getRealXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount)
|
||||||
{
|
{
|
||||||
xfbCount = 1;
|
xfbCount = 1;
|
||||||
|
|
||||||
m_realXFBSource.texWidth = MAX_XFB_WIDTH;
|
m_realXFBSource.texWidth = MAX_XFB_WIDTH;
|
||||||
m_realXFBSource.texHeight = MAX_XFB_HEIGHT;
|
m_realXFBSource.texHeight = MAX_XFB_HEIGHT;
|
||||||
|
|
||||||
m_realXFBSource.srcAddr = xfbAddr;
|
m_realXFBSource.srcAddr = xfbAddr;
|
||||||
m_realXFBSource.srcWidth = fbWidth;
|
m_realXFBSource.srcWidth = fbWidth;
|
||||||
m_realXFBSource.srcHeight = fbHeight;
|
m_realXFBSource.srcHeight = fbHeight;
|
||||||
|
|
||||||
// OpenGL texture coordinates originate at the lower left, which is why
|
// OpenGL texture coordinates originate at the lower left, which is why
|
||||||
// sourceRc.top = fbHeight and sourceRc.bottom = 0.
|
// sourceRc.top = fbHeight and sourceRc.bottom = 0.
|
||||||
m_realXFBSource.sourceRc.left = 0;
|
m_realXFBSource.sourceRc.left = 0;
|
||||||
m_realXFBSource.sourceRc.top = fbHeight;
|
m_realXFBSource.sourceRc.top = fbHeight;
|
||||||
m_realXFBSource.sourceRc.right = fbWidth;
|
m_realXFBSource.sourceRc.right = fbWidth;
|
||||||
m_realXFBSource.sourceRc.bottom = 0;
|
m_realXFBSource.sourceRc.bottom = 0;
|
||||||
|
|
||||||
if (!m_realXFBSource.texture)
|
if (!m_realXFBSource.texture)
|
||||||
{
|
{
|
||||||
glGenTextures(1, &m_realXFBSource.texture);
|
glGenTextures(1, &m_realXFBSource.texture);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_realXFBSource.texture);
|
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_realXFBSource.texture);
|
||||||
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, MAX_XFB_WIDTH, MAX_XFB_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
|
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, MAX_XFB_WIDTH, MAX_XFB_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
|
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode YUYV data from GameCube RAM
|
// Decode YUYV data from GameCube RAM
|
||||||
TextureConverter::DecodeToTexture(xfbAddr, fbWidth, fbHeight, m_realXFBSource.texture);
|
TextureConverter::DecodeToTexture(xfbAddr, fbWidth, fbHeight, m_realXFBSource.texture);
|
||||||
|
|
||||||
m_overlappingXFBArray[0] = &m_realXFBSource;
|
m_overlappingXFBArray[0] = &m_realXFBSource;
|
||||||
|
|
||||||
return &m_overlappingXFBArray[0];
|
return &m_overlappingXFBArray[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramebufferManager::SetFramebuffer(GLuint fb)
|
void FramebufferManager::SetFramebuffer(GLuint fb)
|
||||||
{
|
{
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb != 0 ? fb : GetEFBFramebuffer());
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb != 0 ? fb : GetEFBFramebuffer());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply AA if enabled
|
// Apply AA if enabled
|
||||||
GLuint FramebufferManager::ResolveAndGetRenderTarget(const EFBRectangle &source_rect)
|
GLuint FramebufferManager::ResolveAndGetRenderTarget(const EFBRectangle &source_rect)
|
||||||
{
|
{
|
||||||
return GetEFBColorTexture(source_rect);
|
return GetEFBColorTexture(source_rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint FramebufferManager::ResolveAndGetDepthTarget(const EFBRectangle &source_rect)
|
GLuint FramebufferManager::ResolveAndGetDepthTarget(const EFBRectangle &source_rect)
|
||||||
{
|
{
|
||||||
return GetEFBDepthTexture(source_rect);
|
return GetEFBDepthTexture(source_rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,135 +1,135 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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/
|
||||||
|
|
||||||
#ifndef _OGL_FRAMEBUFFERMANAGER_H_
|
#ifndef _OGL_FRAMEBUFFERMANAGER_H_
|
||||||
#define _OGL_FRAMEBUFFERMANAGER_H_
|
#define _OGL_FRAMEBUFFERMANAGER_H_
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
#include "OGL_GLUtil.h"
|
#include "OGL_GLUtil.h"
|
||||||
|
|
||||||
#include "../FramebufferManager.h"
|
#include "../FramebufferManager.h"
|
||||||
|
|
||||||
namespace OGL
|
namespace OGL
|
||||||
{
|
{
|
||||||
|
|
||||||
// On the GameCube, the game sends a request for the graphics processor to
|
// On the GameCube, the game sends a request for the graphics processor to
|
||||||
// transfer its internal EFB (Embedded Framebuffer) to an area in GameCube RAM
|
// transfer its internal EFB (Embedded Framebuffer) to an area in GameCube RAM
|
||||||
// called the XFB (External Framebuffer). The size and location of the XFB is
|
// called the XFB (External Framebuffer). The size and location of the XFB is
|
||||||
// decided at the time of the copy, and the format is always YUYV. The video
|
// decided at the time of the copy, and the format is always YUYV. The video
|
||||||
// interface is given a pointer to the XFB, which will be decoded and
|
// interface is given a pointer to the XFB, which will be decoded and
|
||||||
// displayed on the TV.
|
// displayed on the TV.
|
||||||
//
|
//
|
||||||
// There are two ways for Dolphin to emulate this:
|
// There are two ways for Dolphin to emulate this:
|
||||||
//
|
//
|
||||||
// Real XFB mode:
|
// Real XFB mode:
|
||||||
//
|
//
|
||||||
// Dolphin will behave like the GameCube and encode the EFB to
|
// Dolphin will behave like the GameCube and encode the EFB to
|
||||||
// a portion of GameCube RAM. The emulated video interface will decode the data
|
// a portion of GameCube RAM. The emulated video interface will decode the data
|
||||||
// for output to the screen.
|
// for output to the screen.
|
||||||
//
|
//
|
||||||
// Advantages: Behaves exactly like the GameCube.
|
// Advantages: Behaves exactly like the GameCube.
|
||||||
// Disadvantages: Resolution will be limited.
|
// Disadvantages: Resolution will be limited.
|
||||||
//
|
//
|
||||||
// Virtual XFB mode:
|
// Virtual XFB mode:
|
||||||
//
|
//
|
||||||
// When a request is made to copy the EFB to an XFB, Dolphin
|
// When a request is made to copy the EFB to an XFB, Dolphin
|
||||||
// will remember the RAM location and size of the XFB in a Virtual XFB list.
|
// will remember the RAM location and size of the XFB in a Virtual XFB list.
|
||||||
// The video interface will look up the XFB in the list and use the enhanced
|
// The video interface will look up the XFB in the list and use the enhanced
|
||||||
// data stored there, if available.
|
// data stored there, if available.
|
||||||
//
|
//
|
||||||
// Advantages: Enables high resolution graphics, better than real hardware.
|
// Advantages: Enables high resolution graphics, better than real hardware.
|
||||||
// Disadvantages: If the GameCube CPU writes directly to the XFB (which is
|
// Disadvantages: If the GameCube CPU writes directly to the XFB (which is
|
||||||
// possible but uncommon), the Virtual XFB will not capture this information.
|
// possible but uncommon), the Virtual XFB will not capture this information.
|
||||||
|
|
||||||
// There may be multiple XFBs in GameCube RAM. This is the maximum number to
|
// There may be multiple XFBs in GameCube RAM. This is the maximum number to
|
||||||
// virtualize.
|
// virtualize.
|
||||||
|
|
||||||
inline bool addrRangesOverlap(u32 aLower, u32 aUpper, u32 bLower, u32 bUpper)
|
inline bool addrRangesOverlap(u32 aLower, u32 aUpper, u32 bLower, u32 bUpper)
|
||||||
{
|
{
|
||||||
return !((aLower >= bUpper) || (bLower >= aUpper));
|
return !((aLower >= bUpper) || (bLower >= aUpper));
|
||||||
}
|
}
|
||||||
|
|
||||||
struct XFBSource : XFBSourceBase
|
struct XFBSource : XFBSourceBase
|
||||||
{
|
{
|
||||||
XFBSource() : texture(0) {}
|
XFBSource() : texture(0) {}
|
||||||
|
|
||||||
void CopyEFB(const TargetRectangle& efbSource);
|
void CopyEFB(const TargetRectangle& efbSource);
|
||||||
|
|
||||||
GLuint texture;
|
GLuint texture;
|
||||||
TargetRectangle sourceRc;
|
TargetRectangle sourceRc;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FramebufferManager : public ::FramebufferManagerBase
|
class FramebufferManager : public ::FramebufferManagerBase
|
||||||
{
|
{
|
||||||
friend struct XFBSource;
|
friend struct XFBSource;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FramebufferManager(int targetWidth, int targetHeight, int msaaSamples, int msaaCoverageSamples);
|
FramebufferManager(int targetWidth, int targetHeight, int msaaSamples, int msaaCoverageSamples);
|
||||||
~FramebufferManager();
|
~FramebufferManager();
|
||||||
|
|
||||||
// To get the EFB in texture form, these functions may have to transfer
|
// To get the EFB in texture form, these functions may have to transfer
|
||||||
// the EFB to a resolved texture first.
|
// the EFB to a resolved texture first.
|
||||||
static GLuint GetEFBColorTexture(const EFBRectangle& sourceRc);
|
static GLuint GetEFBColorTexture(const EFBRectangle& sourceRc);
|
||||||
static GLuint GetEFBDepthTexture(const EFBRectangle& sourceRc);
|
static GLuint GetEFBDepthTexture(const EFBRectangle& sourceRc);
|
||||||
|
|
||||||
static GLuint GetEFBFramebuffer() { return m_efbFramebuffer; }
|
static GLuint GetEFBFramebuffer() { return m_efbFramebuffer; }
|
||||||
|
|
||||||
// Resolved framebuffer is only used in MSAA mode.
|
// Resolved framebuffer is only used in MSAA mode.
|
||||||
static GLuint GetResolvedFramebuffer() { return m_resolvedFramebuffer; }
|
static GLuint GetResolvedFramebuffer() { return m_resolvedFramebuffer; }
|
||||||
|
|
||||||
static void SetFramebuffer(GLuint fb);
|
static void SetFramebuffer(GLuint fb);
|
||||||
|
|
||||||
// If in MSAA mode, this will perform a resolve of the specified rectangle, and return the resolve target as a texture ID.
|
// If in MSAA mode, this will perform a resolve of the specified rectangle, and return the resolve target as a texture ID.
|
||||||
// Thus, this call may be expensive. Don't repeat it unnecessarily.
|
// Thus, this call may be expensive. Don't repeat it unnecessarily.
|
||||||
// If not in MSAA mode, will just return the render target texture ID.
|
// If not in MSAA mode, will just return the render target texture ID.
|
||||||
// After calling this, before you render anything else, you MUST bind the framebuffer you want to draw to.
|
// After calling this, before you render anything else, you MUST bind the framebuffer you want to draw to.
|
||||||
static GLuint ResolveAndGetRenderTarget(const EFBRectangle &rect);
|
static GLuint ResolveAndGetRenderTarget(const EFBRectangle &rect);
|
||||||
|
|
||||||
// Same as above but for the depth Target.
|
// Same as above but for the depth Target.
|
||||||
// After calling this, before you render anything else, you MUST bind the framebuffer you want to draw to.
|
// After calling this, before you render anything else, you MUST bind the framebuffer you want to draw to.
|
||||||
static GLuint ResolveAndGetDepthTarget(const EFBRectangle &rect);
|
static GLuint ResolveAndGetDepthTarget(const EFBRectangle &rect);
|
||||||
|
|
||||||
XFBSourceBase* CreateXFBSource(unsigned int target_width, unsigned int target_height);
|
XFBSourceBase* CreateXFBSource(unsigned int target_width, unsigned int target_height);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static GLuint m_efbFramebuffer;
|
static GLuint m_efbFramebuffer;
|
||||||
static GLuint m_xfbFramebuffer; // Only used in MSAA mode
|
static GLuint m_xfbFramebuffer; // Only used in MSAA mode
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void copyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc);
|
static void copyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc);
|
||||||
static const XFBSourceBase** getRealXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount);
|
static const XFBSourceBase** getRealXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount);
|
||||||
|
|
||||||
static int m_targetWidth;
|
static int m_targetWidth;
|
||||||
static int m_targetHeight;
|
static int m_targetHeight;
|
||||||
static int m_msaaSamples;
|
static int m_msaaSamples;
|
||||||
static int m_msaaCoverageSamples;
|
static int m_msaaCoverageSamples;
|
||||||
|
|
||||||
static GLuint m_efbColor; // Renderbuffer in MSAA mode; Texture otherwise
|
static GLuint m_efbColor; // Renderbuffer in MSAA mode; Texture otherwise
|
||||||
static GLuint m_efbDepth; // Renderbuffer in MSAA mode; Texture otherwise
|
static GLuint m_efbDepth; // Renderbuffer in MSAA mode; Texture otherwise
|
||||||
|
|
||||||
// Only used in MSAA mode.
|
// Only used in MSAA mode.
|
||||||
static GLuint m_resolvedFramebuffer;
|
static GLuint m_resolvedFramebuffer;
|
||||||
static GLuint m_resolvedColorTexture;
|
static GLuint m_resolvedColorTexture;
|
||||||
static GLuint m_resolvedDepthTexture;
|
static GLuint m_resolvedDepthTexture;
|
||||||
|
|
||||||
static XFBSource m_realXFBSource; // Only used in Real XFB mode
|
static XFBSource m_realXFBSource; // Only used in Real XFB mode
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,145 +1,145 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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/
|
||||||
|
|
||||||
#ifndef _GLINIT_H_
|
#ifndef _GLINIT_H_
|
||||||
#define _GLINIT_H_
|
#define _GLINIT_H_
|
||||||
|
|
||||||
// Common
|
// Common
|
||||||
#include "MathUtil.h"
|
#include "MathUtil.h"
|
||||||
|
|
||||||
// VideoCommon
|
// VideoCommon
|
||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
|
|
||||||
#include "pluginspecs_video.h"
|
#include "pluginspecs_video.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
#define GLEW_STATIC
|
#define GLEW_STATIC
|
||||||
|
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include <GL/wglew.h>
|
#include <GL/wglew.h>
|
||||||
|
|
||||||
#else // linux and apple basic definitions
|
#else // linux and apple basic definitions
|
||||||
|
|
||||||
#if defined(USE_WX) && USE_WX
|
#if defined(USE_WX) && USE_WX
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include "wx/wx.h"
|
#include "wx/wx.h"
|
||||||
#include "wx/glcanvas.h"
|
#include "wx/glcanvas.h"
|
||||||
|
|
||||||
#elif defined(HAVE_X11) && HAVE_X11
|
#elif defined(HAVE_X11) && HAVE_X11
|
||||||
#include <GL/glxew.h>
|
#include <GL/glxew.h>
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/keysym.h>
|
#include <X11/keysym.h>
|
||||||
#include "Thread.h"
|
#include "Thread.h"
|
||||||
|
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include "cocoaGL.h"
|
#include "cocoaGL.h"
|
||||||
#endif // end USE_WX
|
#endif // end USE_WX
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
#include <OpenGL/gl.h>
|
#include <OpenGL/gl.h>
|
||||||
#else
|
#else
|
||||||
#include <GL/gl.h>
|
#include <GL/gl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // linux basic definitions
|
#endif // linux basic definitions
|
||||||
|
|
||||||
#ifndef GL_DEPTH24_STENCIL8_EXT // allows FBOs to support stencils
|
#ifndef GL_DEPTH24_STENCIL8_EXT // allows FBOs to support stencils
|
||||||
#define GL_DEPTH_STENCIL_EXT 0x84F9
|
#define GL_DEPTH_STENCIL_EXT 0x84F9
|
||||||
#define GL_UNSIGNED_INT_24_8_EXT 0x84FA
|
#define GL_UNSIGNED_INT_24_8_EXT 0x84FA
|
||||||
#define GL_DEPTH24_STENCIL8_EXT 0x88F0
|
#define GL_DEPTH24_STENCIL8_EXT 0x88F0
|
||||||
#define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1
|
#define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
#if defined(USE_WX) && USE_WX
|
#if defined(USE_WX) && USE_WX
|
||||||
wxGLCanvas *glCanvas;
|
wxGLCanvas *glCanvas;
|
||||||
wxPanel *panel;
|
wxPanel *panel;
|
||||||
wxGLContext *glCtxt;
|
wxGLContext *glCtxt;
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
NSWindow *cocoaWin;
|
NSWindow *cocoaWin;
|
||||||
NSOpenGLContext *cocoaCtx;
|
NSOpenGLContext *cocoaCtx;
|
||||||
#elif defined(HAVE_X11) && HAVE_X11
|
#elif defined(HAVE_X11) && HAVE_X11
|
||||||
int screen;
|
int screen;
|
||||||
Window win;
|
Window win;
|
||||||
Window parent;
|
Window parent;
|
||||||
Display *dpy;
|
Display *dpy;
|
||||||
XVisualInfo *vi;
|
XVisualInfo *vi;
|
||||||
GLXContext ctx;
|
GLXContext ctx;
|
||||||
XSetWindowAttributes attr;
|
XSetWindowAttributes attr;
|
||||||
Common::Thread *xEventThread;
|
Common::Thread *xEventThread;
|
||||||
int x, y;
|
int x, y;
|
||||||
#endif
|
#endif
|
||||||
unsigned int width, height;
|
unsigned int width, height;
|
||||||
} GLWindow;
|
} GLWindow;
|
||||||
|
|
||||||
extern GLWindow GLWin;
|
extern GLWindow GLWin;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Public OpenGL util
|
// Public OpenGL util
|
||||||
|
|
||||||
//#if defined __APPLE__ || defined __linux__ || defined _WIN32
|
//#if defined __APPLE__ || defined __linux__ || defined _WIN32
|
||||||
//#include <Cg/cg.h>
|
//#include <Cg/cg.h>
|
||||||
//#include <Cg/cgGL.h>
|
//#include <Cg/cgGL.h>
|
||||||
//#define HAVE_CG 1
|
//#define HAVE_CG 1
|
||||||
//extern CGcontext g_cgcontext;
|
//extern CGcontext g_cgcontext;
|
||||||
//extern CGprofile g_cgvProf, g_cgfProf;
|
//extern CGprofile g_cgvProf, g_cgfProf;
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
namespace OGL
|
namespace OGL
|
||||||
{
|
{
|
||||||
|
|
||||||
// Initialization / upkeep
|
// Initialization / upkeep
|
||||||
bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _width, int _height);
|
bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _width, int _height);
|
||||||
void OpenGL_Shutdown();
|
void OpenGL_Shutdown();
|
||||||
void OpenGL_Update();
|
void OpenGL_Update();
|
||||||
bool OpenGL_MakeCurrent();
|
bool OpenGL_MakeCurrent();
|
||||||
void OpenGL_SwapBuffers();
|
void OpenGL_SwapBuffers();
|
||||||
|
|
||||||
// Get status
|
// Get status
|
||||||
u32 OpenGL_GetBackbufferWidth();
|
u32 OpenGL_GetBackbufferWidth();
|
||||||
u32 OpenGL_GetBackbufferHeight();
|
u32 OpenGL_GetBackbufferHeight();
|
||||||
|
|
||||||
// Set things
|
// Set things
|
||||||
void OpenGL_SetWindowText(const char *text);
|
void OpenGL_SetWindowText(const char *text);
|
||||||
|
|
||||||
// Error reporting - use the convenient macros.
|
// Error reporting - use the convenient macros.
|
||||||
void OpenGL_ReportARBProgramError();
|
void OpenGL_ReportARBProgramError();
|
||||||
GLuint OpenGL_ReportGLError(const char *function, const char *file, int line);
|
GLuint OpenGL_ReportGLError(const char *function, const char *file, int line);
|
||||||
bool OpenGL_ReportFBOError(const char *function, const char *file, int line);
|
bool OpenGL_ReportFBOError(const char *function, const char *file, int line);
|
||||||
|
|
||||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||||
#define GL_REPORT_ERROR() OpenGL_ReportGLError(__FUNCTION__, __FILE__, __LINE__)
|
#define GL_REPORT_ERROR() OpenGL_ReportGLError(__FUNCTION__, __FILE__, __LINE__)
|
||||||
#define GL_REPORT_ERRORD() OpenGL_ReportGLError(__FUNCTION__, __FILE__, __LINE__)
|
#define GL_REPORT_ERRORD() OpenGL_ReportGLError(__FUNCTION__, __FILE__, __LINE__)
|
||||||
#define GL_REPORT_FBO_ERROR() OpenGL_ReportFBOError(__FUNCTION__, __FILE__, __LINE__)
|
#define GL_REPORT_FBO_ERROR() OpenGL_ReportFBOError(__FUNCTION__, __FILE__, __LINE__)
|
||||||
#define GL_REPORT_PROGRAM_ERROR() OpenGL_ReportARBProgramError()
|
#define GL_REPORT_PROGRAM_ERROR() OpenGL_ReportARBProgramError()
|
||||||
#else
|
#else
|
||||||
#define GL_REPORT_ERROR() GL_NO_ERROR
|
#define GL_REPORT_ERROR() GL_NO_ERROR
|
||||||
#define GL_REPORT_ERRORD() (void)GL_NO_ERROR
|
#define GL_REPORT_ERRORD() (void)GL_NO_ERROR
|
||||||
#define GL_REPORT_FBO_ERROR() (void)true
|
#define GL_REPORT_FBO_ERROR() (void)true
|
||||||
#define GL_REPORT_PROGRAM_ERROR() (void)0
|
#define GL_REPORT_PROGRAM_ERROR() (void)0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // _GLINIT_H_
|
#endif // _GLINIT_H_
|
||||||
|
|||||||
@@ -1,178 +1,178 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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/
|
||||||
|
|
||||||
#ifndef _OGL_GLWINDOW_H_
|
#ifndef _OGL_GLWINDOW_H_
|
||||||
#define _OGL_GLWINDOW_H_
|
#define _OGL_GLWINDOW_H_
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
|
||||||
#include "OGL_Globals.h"
|
#include "OGL_Globals.h"
|
||||||
|
|
||||||
#include "pluginspecs_video.h"
|
#include "pluginspecs_video.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define GLEW_STATIC
|
#define GLEW_STATIC
|
||||||
|
|
||||||
#include <GLew/glew.h>
|
#include <GLew/glew.h>
|
||||||
#include <GLew/wglew.h>
|
#include <GLew/wglew.h>
|
||||||
#include <GLew/gl.h>
|
#include <GLew/gl.h>
|
||||||
#include <GLew/glext.h>
|
#include <GLew/glext.h>
|
||||||
#else
|
#else
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
#include <OpenGL/gl.h>
|
#include <OpenGL/gl.h>
|
||||||
#else
|
#else
|
||||||
#include <GL/gl.h>
|
#include <GL/gl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace OGL
|
namespace OGL
|
||||||
{
|
{
|
||||||
|
|
||||||
enum OGL_Props
|
enum OGL_Props
|
||||||
{
|
{
|
||||||
OGL_FULLSCREEN,
|
OGL_FULLSCREEN,
|
||||||
OGL_KEEPRATIO,
|
OGL_KEEPRATIO,
|
||||||
OGL_HIDECURSOR,
|
OGL_HIDECURSOR,
|
||||||
OGL_PROP_COUNT
|
OGL_PROP_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
struct res
|
struct res
|
||||||
{
|
{
|
||||||
u32 x;
|
u32 x;
|
||||||
u32 y;
|
u32 y;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GLWindow
|
class GLWindow
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// TODO: what is xmax and ymax? do we need [xy]render?
|
// TODO: what is xmax and ymax? do we need [xy]render?
|
||||||
u32 xWin, yWin; // Windows' size
|
u32 xWin, yWin; // Windows' size
|
||||||
int xOffset, yOffset; // Offset in window
|
int xOffset, yOffset; // Offset in window
|
||||||
float xMax, yMax; // ???
|
float xMax, yMax; // ???
|
||||||
u32 xRender, yRender; // Render area
|
u32 xRender, yRender; // Render area
|
||||||
|
|
||||||
bool properties[OGL_PROP_COUNT];
|
bool properties[OGL_PROP_COUNT];
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
EventHandler* eventHandler;
|
EventHandler* eventHandler;
|
||||||
res origRes, currFullRes, currWinRes;
|
res origRes, currFullRes, currWinRes;
|
||||||
static std::vector<res> fullResolutions;
|
static std::vector<res> fullResolutions;
|
||||||
virtual void SetRender(u32 x, u32 y)
|
virtual void SetRender(u32 x, u32 y)
|
||||||
{
|
{
|
||||||
xRender = x;
|
xRender = x;
|
||||||
yRender = y;
|
yRender = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const std::vector<res>& getFsResolutions()
|
static const std::vector<res>& getFsResolutions()
|
||||||
{
|
{
|
||||||
return fullResolutions;
|
return fullResolutions;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addFSResolution(res fsr)
|
static void addFSResolution(res fsr)
|
||||||
{
|
{
|
||||||
fullResolutions.push_back(fsr);
|
fullResolutions.push_back(fsr);
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual void SwapBuffers() {};
|
virtual void SwapBuffers() {};
|
||||||
virtual void SetWindowText(const char *text) {};
|
virtual void SetWindowText(const char *text) {};
|
||||||
virtual bool PeekMessages() {return false;};
|
virtual bool PeekMessages() {return false;};
|
||||||
virtual void Update() {};
|
virtual void Update() {};
|
||||||
virtual bool MakeCurrent() {return false;};
|
virtual bool MakeCurrent() {return false;};
|
||||||
|
|
||||||
virtual void updateDim()
|
virtual void updateDim()
|
||||||
{
|
{
|
||||||
if (GetProperty(OGL_FULLSCREEN))
|
if (GetProperty(OGL_FULLSCREEN))
|
||||||
SetWinSize(currFullRes.x, currFullRes.y);
|
SetWinSize(currFullRes.x, currFullRes.y);
|
||||||
else
|
else
|
||||||
// Set the windowed resolution
|
// Set the windowed resolution
|
||||||
SetWinSize(currWinRes.x, currWinRes.y);
|
SetWinSize(currWinRes.x, currWinRes.y);
|
||||||
|
|
||||||
float FactorX = 640.0f / (float)GetXwin();
|
float FactorX = 640.0f / (float)GetXwin();
|
||||||
float FactorY = 480.0f / (float)GetYwin();
|
float FactorY = 480.0f / (float)GetYwin();
|
||||||
//float Max = (FactorX < FactorY) ? FactorX : FactorY;
|
//float Max = (FactorX < FactorY) ? FactorX : FactorY;
|
||||||
|
|
||||||
SetMax(1.0f / FactorX, 1.0f / FactorY);
|
SetMax(1.0f / FactorX, 1.0f / FactorY);
|
||||||
SetOffset(0,0);
|
SetOffset(0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetEventHandler(EventHandler *eh) { eventHandler = eh;}
|
void SetEventHandler(EventHandler *eh) { eventHandler = eh;}
|
||||||
bool GetProperty(OGL_Props prop) {return properties[prop];}
|
bool GetProperty(OGL_Props prop) {return properties[prop];}
|
||||||
virtual bool SetProperty(OGL_Props prop, bool value)
|
virtual bool SetProperty(OGL_Props prop, bool value)
|
||||||
{return properties[prop] = value;}
|
{return properties[prop] = value;}
|
||||||
|
|
||||||
u32 GetXrender() {return xRender;}
|
u32 GetXrender() {return xRender;}
|
||||||
u32 GetYrender() {return yRender;}
|
u32 GetYrender() {return yRender;}
|
||||||
|
|
||||||
u32 GetXwin() {return xWin;}
|
u32 GetXwin() {return xWin;}
|
||||||
u32 GetYwin() {return yWin;}
|
u32 GetYwin() {return yWin;}
|
||||||
void SetWinSize(u32 x, u32 y)
|
void SetWinSize(u32 x, u32 y)
|
||||||
{
|
{
|
||||||
xWin = x;
|
xWin = x;
|
||||||
yWin = y;
|
yWin = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetYoff() {return yOffset;}
|
int GetYoff() {return yOffset;}
|
||||||
int GetXoff() {return xOffset;}
|
int GetXoff() {return xOffset;}
|
||||||
void SetOffset(int x, int y)
|
void SetOffset(int x, int y)
|
||||||
{
|
{
|
||||||
yOffset = y;
|
yOffset = y;
|
||||||
xOffset = x;
|
xOffset = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetMax(float x, float y)
|
void SetMax(float x, float y)
|
||||||
{
|
{
|
||||||
yMax = y;
|
yMax = y;
|
||||||
xMax = x;
|
xMax = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
float GetXmax() {return xMax;}
|
float GetXmax() {return xMax;}
|
||||||
float GetYmax() {return yMax;}
|
float GetYmax() {return yMax;}
|
||||||
|
|
||||||
static bool valid() { return false;}
|
static bool valid() { return false;}
|
||||||
|
|
||||||
GLWindow()
|
GLWindow()
|
||||||
{
|
{
|
||||||
// Load defaults
|
// Load defaults
|
||||||
sscanf(g_Config.iFSResolution, "%dx%d",
|
sscanf(g_Config.iFSResolution, "%dx%d",
|
||||||
&currFullRes.x, &currFullRes.y);
|
&currFullRes.x, &currFullRes.y);
|
||||||
|
|
||||||
sscanf(g_Config.iInternalRes, "%dx%d",
|
sscanf(g_Config.iInternalRes, "%dx%d",
|
||||||
&currWinRes.x, &currWinRes.y);
|
&currWinRes.x, &currWinRes.y);
|
||||||
|
|
||||||
SetProperty(OGL_FULLSCREEN, g_Config.bFullscreen);
|
SetProperty(OGL_FULLSCREEN, g_Config.bFullscreen);
|
||||||
// What does this do?
|
// What does this do?
|
||||||
SetProperty(OGL_KEEPRATIO, g_Config.bKeepAR43);
|
SetProperty(OGL_KEEPRATIO, g_Config.bKeepAR43);
|
||||||
SetProperty(OGL_HIDECURSOR, g_Config.bHideCursor);
|
SetProperty(OGL_HIDECURSOR, g_Config.bHideCursor);
|
||||||
|
|
||||||
updateDim();
|
updateDim();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// setResolution
|
// setResolution
|
||||||
// resolution iter
|
// resolution iter
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // _GLWINDOW_H_
|
#endif // _GLWINDOW_H_
|
||||||
|
|||||||
@@ -1,310 +1,310 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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/
|
||||||
|
|
||||||
// Common
|
// Common
|
||||||
#include "x64Emitter.h"
|
#include "x64Emitter.h"
|
||||||
#include "ABI.h"
|
#include "ABI.h"
|
||||||
#include "MemoryUtil.h"
|
#include "MemoryUtil.h"
|
||||||
|
|
||||||
// VideoCommon
|
// VideoCommon
|
||||||
#include "Profiler.h"
|
#include "Profiler.h"
|
||||||
#include "VertexShaderGen.h"
|
#include "VertexShaderGen.h"
|
||||||
#include "NativeVertexFormat.h"
|
#include "NativeVertexFormat.h"
|
||||||
#include "NativeVertexWriter.h"
|
#include "NativeVertexWriter.h"
|
||||||
#include "CPMemory.h"
|
#include "CPMemory.h"
|
||||||
|
|
||||||
// OGL
|
// OGL
|
||||||
#include "OGL_GLUtil.h"
|
#include "OGL_GLUtil.h"
|
||||||
#include "OGL_VertexManager.h"
|
#include "OGL_VertexManager.h"
|
||||||
|
|
||||||
#include "../Main.h"
|
#include "../Main.h"
|
||||||
|
|
||||||
namespace OGL
|
namespace OGL
|
||||||
{
|
{
|
||||||
|
|
||||||
#define COMPILED_CODE_SIZE 4096
|
#define COMPILED_CODE_SIZE 4096
|
||||||
|
|
||||||
u32 s_prevcomponents; // previous state set
|
u32 s_prevcomponents; // previous state set
|
||||||
/*
|
/*
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#ifdef _M_IX86
|
#ifdef _M_IX86
|
||||||
#define USE_JIT
|
#define USE_JIT
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
*/
|
*/
|
||||||
// Note the use of CallCdeclFunction3I etc.
|
// Note the use of CallCdeclFunction3I etc.
|
||||||
// This is a horrible hack that is necessary because in 64-bit mode, Opengl32.dll is based way, way above the 32-bit
|
// This is a horrible hack that is necessary because in 64-bit mode, Opengl32.dll is based way, way above the 32-bit
|
||||||
// address space that is within reach of a CALL, and just doing &fn gives us these high uncallable addresses. So we
|
// address space that is within reach of a CALL, and just doing &fn gives us these high uncallable addresses. So we
|
||||||
// want to grab the function pointers from the import table instead.
|
// want to grab the function pointers from the import table instead.
|
||||||
|
|
||||||
// This problem does not apply to glew functions, only core opengl32 functions.
|
// This problem does not apply to glew functions, only core opengl32 functions.
|
||||||
|
|
||||||
// Here's some global state. We only use this to keep track of what we've sent to the OpenGL state
|
// Here's some global state. We only use this to keep track of what we've sent to the OpenGL state
|
||||||
// machine.
|
// machine.
|
||||||
|
|
||||||
#ifdef USE_JIT
|
#ifdef USE_JIT
|
||||||
DECLARE_IMPORT(glNormalPointer);
|
DECLARE_IMPORT(glNormalPointer);
|
||||||
DECLARE_IMPORT(glVertexPointer);
|
DECLARE_IMPORT(glVertexPointer);
|
||||||
DECLARE_IMPORT(glColorPointer);
|
DECLARE_IMPORT(glColorPointer);
|
||||||
DECLARE_IMPORT(glTexCoordPointer);
|
DECLARE_IMPORT(glTexCoordPointer);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class GLVertexFormat : public NativeVertexFormat
|
class GLVertexFormat : public NativeVertexFormat
|
||||||
{
|
{
|
||||||
u8 *m_compiledCode;
|
u8 *m_compiledCode;
|
||||||
PortableVertexDeclaration vtx_decl;
|
PortableVertexDeclaration vtx_decl;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GLVertexFormat();
|
GLVertexFormat();
|
||||||
~GLVertexFormat();
|
~GLVertexFormat();
|
||||||
|
|
||||||
virtual void Initialize(const PortableVertexDeclaration &_vtx_decl);
|
virtual void Initialize(const PortableVertexDeclaration &_vtx_decl);
|
||||||
virtual void SetupVertexPointers() const;
|
virtual void SetupVertexPointers() const;
|
||||||
virtual void EnableComponents(u32 components);
|
virtual void EnableComponents(u32 components);
|
||||||
};
|
};
|
||||||
|
|
||||||
NativeVertexFormat* VertexManager::CreateNativeVertexFormat()
|
NativeVertexFormat* VertexManager::CreateNativeVertexFormat()
|
||||||
{
|
{
|
||||||
return new GLVertexFormat;
|
return new GLVertexFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLVertexFormat::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);
|
||||||
if (m_compiledCode)
|
if (m_compiledCode)
|
||||||
memset(m_compiledCode, 0, COMPILED_CODE_SIZE);
|
memset(m_compiledCode, 0, COMPILED_CODE_SIZE);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
GLVertexFormat::~GLVertexFormat()
|
GLVertexFormat::~GLVertexFormat()
|
||||||
{
|
{
|
||||||
#ifdef USE_JIT
|
#ifdef USE_JIT
|
||||||
FreeMemoryPages(m_compiledCode, COMPILED_CODE_SIZE);
|
FreeMemoryPages(m_compiledCode, COMPILED_CODE_SIZE);
|
||||||
m_compiledCode = 0;
|
m_compiledCode = 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
inline GLuint VarToGL(VarType t)
|
inline GLuint VarToGL(VarType t)
|
||||||
{
|
{
|
||||||
static const GLuint lookup[5] = {
|
static const GLuint lookup[5] = {
|
||||||
GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_FLOAT
|
GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_FLOAT
|
||||||
};
|
};
|
||||||
return lookup[t];
|
return lookup[t];
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl)
|
void GLVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl)
|
||||||
{
|
{
|
||||||
vertex_stride = _vtx_decl.stride;
|
vertex_stride = _vtx_decl.stride;
|
||||||
using namespace Gen;
|
using namespace Gen;
|
||||||
|
|
||||||
// We will not allow vertex components causing uneven strides.
|
// We will not allow vertex components causing uneven strides.
|
||||||
if (_vtx_decl.stride & 3)
|
if (_vtx_decl.stride & 3)
|
||||||
PanicAlert("Uneven vertex stride: %i", _vtx_decl.stride);
|
PanicAlert("Uneven vertex stride: %i", _vtx_decl.stride);
|
||||||
|
|
||||||
#ifdef USE_JIT
|
#ifdef USE_JIT
|
||||||
Gen::XEmitter emit(m_compiledCode);
|
Gen::XEmitter emit(m_compiledCode);
|
||||||
// Alright, we have our vertex declaration. Compile some crazy code to set it quickly using GL.
|
// Alright, we have our vertex declaration. Compile some crazy code to set it quickly using GL.
|
||||||
emit.ABI_EmitPrologue(6);
|
emit.ABI_EmitPrologue(6);
|
||||||
|
|
||||||
emit.CallCdeclFunction4_I(glVertexPointer, 3, GL_FLOAT, _vtx_decl.stride, 0);
|
emit.CallCdeclFunction4_I(glVertexPointer, 3, GL_FLOAT, _vtx_decl.stride, 0);
|
||||||
|
|
||||||
if (_vtx_decl.num_normals >= 1)
|
if (_vtx_decl.num_normals >= 1)
|
||||||
{
|
{
|
||||||
emit.CallCdeclFunction3_I(glNormalPointer, VarToGL(_vtx_decl.normal_gl_type), _vtx_decl.stride, _vtx_decl.normal_offset[0]);
|
emit.CallCdeclFunction3_I(glNormalPointer, VarToGL(_vtx_decl.normal_gl_type), _vtx_decl.stride, _vtx_decl.normal_offset[0]);
|
||||||
if (_vtx_decl.num_normals == 3) {
|
if (_vtx_decl.num_normals == 3) {
|
||||||
emit.CallCdeclFunction6((void *)glVertexAttribPointer, SHADER_NORM1_ATTRIB, _vtx_decl.normal_gl_size, VarToGL(_vtx_decl.normal_gl_type), GL_TRUE, _vtx_decl.stride, _vtx_decl.normal_offset[1]);
|
emit.CallCdeclFunction6((void *)glVertexAttribPointer, SHADER_NORM1_ATTRIB, _vtx_decl.normal_gl_size, VarToGL(_vtx_decl.normal_gl_type), GL_TRUE, _vtx_decl.stride, _vtx_decl.normal_offset[1]);
|
||||||
emit.CallCdeclFunction6((void *)glVertexAttribPointer, SHADER_NORM2_ATTRIB, _vtx_decl.normal_gl_size, VarToGL(_vtx_decl.normal_gl_type), GL_TRUE, _vtx_decl.stride, _vtx_decl.normal_offset[2]);
|
emit.CallCdeclFunction6((void *)glVertexAttribPointer, SHADER_NORM2_ATTRIB, _vtx_decl.normal_gl_size, VarToGL(_vtx_decl.normal_gl_type), GL_TRUE, _vtx_decl.stride, _vtx_decl.normal_offset[2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++)
|
for (int i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
if (_vtx_decl.color_offset[i] != -1)
|
if (_vtx_decl.color_offset[i] != -1)
|
||||||
{
|
{
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
emit.CallCdeclFunction4_I(glColorPointer, 4, GL_UNSIGNED_BYTE, _vtx_decl.stride, _vtx_decl.color_offset[i]);
|
emit.CallCdeclFunction4_I(glColorPointer, 4, GL_UNSIGNED_BYTE, _vtx_decl.stride, _vtx_decl.color_offset[i]);
|
||||||
else
|
else
|
||||||
emit.CallCdeclFunction4((void *)glSecondaryColorPointer, 4, GL_UNSIGNED_BYTE, _vtx_decl.stride, _vtx_decl.color_offset[i]);
|
emit.CallCdeclFunction4((void *)glSecondaryColorPointer, 4, GL_UNSIGNED_BYTE, _vtx_decl.stride, _vtx_decl.color_offset[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
if (_vtx_decl.texcoord_offset[i] != -1)
|
if (_vtx_decl.texcoord_offset[i] != -1)
|
||||||
{
|
{
|
||||||
int id = GL_TEXTURE0 + i;
|
int id = GL_TEXTURE0 + i;
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
emit.MOV(32, R(RCX), Imm32(id));
|
emit.MOV(32, R(RCX), Imm32(id));
|
||||||
#else
|
#else
|
||||||
emit.MOV(32, R(RDI), Imm32(id));
|
emit.MOV(32, R(RDI), Imm32(id));
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
emit.ABI_AlignStack(1 * 4);
|
emit.ABI_AlignStack(1 * 4);
|
||||||
emit.PUSH(32, Imm32(id));
|
emit.PUSH(32, Imm32(id));
|
||||||
#endif
|
#endif
|
||||||
emit.CALL((void *)glClientActiveTexture);
|
emit.CALL((void *)glClientActiveTexture);
|
||||||
#ifndef _M_X64
|
#ifndef _M_X64
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
// don't inc stack on windows, stdcall
|
// don't inc stack on windows, stdcall
|
||||||
#else
|
#else
|
||||||
emit.ABI_RestoreStack(1 * 4);
|
emit.ABI_RestoreStack(1 * 4);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
emit.CallCdeclFunction4_I(
|
emit.CallCdeclFunction4_I(
|
||||||
glTexCoordPointer, _vtx_decl.texcoord_size[i], VarToGL(_vtx_decl.texcoord_gl_type[i]),
|
glTexCoordPointer, _vtx_decl.texcoord_size[i], VarToGL(_vtx_decl.texcoord_gl_type[i]),
|
||||||
_vtx_decl.stride, _vtx_decl.texcoord_offset[i]);
|
_vtx_decl.stride, _vtx_decl.texcoord_offset[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_vtx_decl.posmtx_offset != -1)
|
if (_vtx_decl.posmtx_offset != -1)
|
||||||
emit.CallCdeclFunction6((void *)glVertexAttribPointer, SHADER_POSMTX_ATTRIB, 4, GL_UNSIGNED_BYTE, GL_FALSE, _vtx_decl.stride, _vtx_decl.posmtx_offset);
|
emit.CallCdeclFunction6((void *)glVertexAttribPointer, SHADER_POSMTX_ATTRIB, 4, GL_UNSIGNED_BYTE, GL_FALSE, _vtx_decl.stride, _vtx_decl.posmtx_offset);
|
||||||
|
|
||||||
emit.ABI_EmitEpilogue(6);
|
emit.ABI_EmitEpilogue(6);
|
||||||
|
|
||||||
if (emit.GetCodePtr() - (u8*)m_compiledCode > COMPILED_CODE_SIZE)
|
if (emit.GetCodePtr() - (u8*)m_compiledCode > COMPILED_CODE_SIZE)
|
||||||
Crash();
|
Crash();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
this->vtx_decl = _vtx_decl;
|
this->vtx_decl = _vtx_decl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLVertexFormat::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
|
||||||
((void (*)())(void*)m_compiledCode)();
|
((void (*)())(void*)m_compiledCode)();
|
||||||
#else
|
#else
|
||||||
glVertexPointer(3, GL_FLOAT, vtx_decl.stride, ::VertexManager::s_pBaseBufferPointer);
|
glVertexPointer(3, GL_FLOAT, vtx_decl.stride, ::VertexManager::s_pBaseBufferPointer);
|
||||||
if (vtx_decl.num_normals >= 1) {
|
if (vtx_decl.num_normals >= 1) {
|
||||||
glNormalPointer(VarToGL(vtx_decl.normal_gl_type), vtx_decl.stride, (void *)(::VertexManager::s_pBaseBufferPointer + vtx_decl.normal_offset[0]));
|
glNormalPointer(VarToGL(vtx_decl.normal_gl_type), vtx_decl.stride, (void *)(::VertexManager::s_pBaseBufferPointer + vtx_decl.normal_offset[0]));
|
||||||
if (vtx_decl.num_normals == 3) {
|
if (vtx_decl.num_normals == 3) {
|
||||||
glVertexAttribPointer(SHADER_NORM1_ATTRIB, vtx_decl.normal_gl_size, VarToGL(vtx_decl.normal_gl_type), GL_TRUE, vtx_decl.stride, (void *)(::VertexManager::s_pBaseBufferPointer + vtx_decl.normal_offset[1]));
|
glVertexAttribPointer(SHADER_NORM1_ATTRIB, vtx_decl.normal_gl_size, VarToGL(vtx_decl.normal_gl_type), GL_TRUE, vtx_decl.stride, (void *)(::VertexManager::s_pBaseBufferPointer + vtx_decl.normal_offset[1]));
|
||||||
glVertexAttribPointer(SHADER_NORM2_ATTRIB, vtx_decl.normal_gl_size, VarToGL(vtx_decl.normal_gl_type), GL_TRUE, vtx_decl.stride, (void *)(::VertexManager::s_pBaseBufferPointer + vtx_decl.normal_offset[2]));
|
glVertexAttribPointer(SHADER_NORM2_ATTRIB, vtx_decl.normal_gl_size, VarToGL(vtx_decl.normal_gl_type), GL_TRUE, vtx_decl.stride, (void *)(::VertexManager::s_pBaseBufferPointer + vtx_decl.normal_offset[2]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
if (vtx_decl.color_offset[i] != -1) {
|
if (vtx_decl.color_offset[i] != -1) {
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
glColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (void *)(::VertexManager::s_pBaseBufferPointer + vtx_decl.color_offset[i]));
|
glColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (void *)(::VertexManager::s_pBaseBufferPointer + vtx_decl.color_offset[i]));
|
||||||
else {
|
else {
|
||||||
glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (void *)(::VertexManager::s_pBaseBufferPointer + vtx_decl.color_offset[i]));
|
glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (void *)(::VertexManager::s_pBaseBufferPointer + vtx_decl.color_offset[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
if (vtx_decl.texcoord_offset[i] != -1) {
|
if (vtx_decl.texcoord_offset[i] != -1) {
|
||||||
int id = GL_TEXTURE0 + i;
|
int id = GL_TEXTURE0 + i;
|
||||||
glClientActiveTexture(id);
|
glClientActiveTexture(id);
|
||||||
glTexCoordPointer(vtx_decl.texcoord_size[i], VarToGL(vtx_decl.texcoord_gl_type[i]),
|
glTexCoordPointer(vtx_decl.texcoord_size[i], VarToGL(vtx_decl.texcoord_gl_type[i]),
|
||||||
vtx_decl.stride, (void *)(::VertexManager::s_pBaseBufferPointer + vtx_decl.texcoord_offset[i]));
|
vtx_decl.stride, (void *)(::VertexManager::s_pBaseBufferPointer + vtx_decl.texcoord_offset[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vtx_decl.posmtx_offset != -1) {
|
if (vtx_decl.posmtx_offset != -1) {
|
||||||
glVertexAttribPointer(SHADER_POSMTX_ATTRIB, 4, GL_UNSIGNED_BYTE, GL_FALSE, vtx_decl.stride, (void *)(::VertexManager::s_pBaseBufferPointer + vtx_decl.posmtx_offset));
|
glVertexAttribPointer(SHADER_POSMTX_ATTRIB, 4, GL_UNSIGNED_BYTE, GL_FALSE, vtx_decl.stride, (void *)(::VertexManager::s_pBaseBufferPointer + vtx_decl.posmtx_offset));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLVertexFormat::EnableComponents(u32 components)
|
void GLVertexFormat::EnableComponents(u32 components)
|
||||||
{
|
{
|
||||||
if (s_prevcomponents != components)
|
if (s_prevcomponents != components)
|
||||||
{
|
{
|
||||||
g_vertex_manager->Flush();
|
g_vertex_manager->Flush();
|
||||||
|
|
||||||
// matrices
|
// matrices
|
||||||
if ((components & VB_HAS_POSMTXIDX) != (s_prevcomponents & VB_HAS_POSMTXIDX))
|
if ((components & VB_HAS_POSMTXIDX) != (s_prevcomponents & VB_HAS_POSMTXIDX))
|
||||||
{
|
{
|
||||||
if (components & VB_HAS_POSMTXIDX)
|
if (components & VB_HAS_POSMTXIDX)
|
||||||
glEnableVertexAttribArray(SHADER_POSMTX_ATTRIB);
|
glEnableVertexAttribArray(SHADER_POSMTX_ATTRIB);
|
||||||
else
|
else
|
||||||
glDisableVertexAttribArray(SHADER_POSMTX_ATTRIB);
|
glDisableVertexAttribArray(SHADER_POSMTX_ATTRIB);
|
||||||
}
|
}
|
||||||
|
|
||||||
// normals
|
// normals
|
||||||
if ((components & VB_HAS_NRM0) != (s_prevcomponents & VB_HAS_NRM0))
|
if ((components & VB_HAS_NRM0) != (s_prevcomponents & VB_HAS_NRM0))
|
||||||
{
|
{
|
||||||
if (components & VB_HAS_NRM0)
|
if (components & VB_HAS_NRM0)
|
||||||
glEnableClientState(GL_NORMAL_ARRAY);
|
glEnableClientState(GL_NORMAL_ARRAY);
|
||||||
else
|
else
|
||||||
glDisableClientState(GL_NORMAL_ARRAY);
|
glDisableClientState(GL_NORMAL_ARRAY);
|
||||||
}
|
}
|
||||||
if ((components & VB_HAS_NRM1) != (s_prevcomponents & VB_HAS_NRM1))
|
if ((components & VB_HAS_NRM1) != (s_prevcomponents & VB_HAS_NRM1))
|
||||||
{
|
{
|
||||||
if (components & VB_HAS_NRM1) {
|
if (components & VB_HAS_NRM1) {
|
||||||
glEnableVertexAttribArray(SHADER_NORM1_ATTRIB);
|
glEnableVertexAttribArray(SHADER_NORM1_ATTRIB);
|
||||||
glEnableVertexAttribArray(SHADER_NORM2_ATTRIB);
|
glEnableVertexAttribArray(SHADER_NORM2_ATTRIB);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
glDisableVertexAttribArray(SHADER_NORM1_ATTRIB);
|
glDisableVertexAttribArray(SHADER_NORM1_ATTRIB);
|
||||||
glDisableVertexAttribArray(SHADER_NORM2_ATTRIB);
|
glDisableVertexAttribArray(SHADER_NORM2_ATTRIB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// color
|
// color
|
||||||
for (int i = 0; i < 2; ++i)
|
for (int i = 0; i < 2; ++i)
|
||||||
{
|
{
|
||||||
if ((components & (VB_HAS_COL0 << i)) != (s_prevcomponents & (VB_HAS_COL0 << i)))
|
if ((components & (VB_HAS_COL0 << i)) != (s_prevcomponents & (VB_HAS_COL0 << i)))
|
||||||
{
|
{
|
||||||
if (components & (VB_HAS_COL0 << i))
|
if (components & (VB_HAS_COL0 << i))
|
||||||
glEnableClientState(i ? GL_SECONDARY_COLOR_ARRAY : GL_COLOR_ARRAY);
|
glEnableClientState(i ? GL_SECONDARY_COLOR_ARRAY : GL_COLOR_ARRAY);
|
||||||
else
|
else
|
||||||
glDisableClientState(i ? GL_SECONDARY_COLOR_ARRAY : GL_COLOR_ARRAY);
|
glDisableClientState(i ? GL_SECONDARY_COLOR_ARRAY : GL_COLOR_ARRAY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// tex
|
// tex
|
||||||
for (int i = 0; i < 8; ++i)
|
for (int i = 0; i < 8; ++i)
|
||||||
{
|
{
|
||||||
if (!g_ActiveConfig.bDisableTexturing)
|
if (!g_ActiveConfig.bDisableTexturing)
|
||||||
{
|
{
|
||||||
if ((components & (VB_HAS_UV0 << i)) != (s_prevcomponents & (VB_HAS_UV0 << i)))
|
if ((components & (VB_HAS_UV0 << i)) != (s_prevcomponents & (VB_HAS_UV0 << i)))
|
||||||
{
|
{
|
||||||
glClientActiveTexture(GL_TEXTURE0 + i);
|
glClientActiveTexture(GL_TEXTURE0 + i);
|
||||||
if (components & (VB_HAS_UV0 << i))
|
if (components & (VB_HAS_UV0 << i))
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
else
|
else
|
||||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
glClientActiveTexture(GL_TEXTURE0 + i);
|
glClientActiveTexture(GL_TEXTURE0 + i);
|
||||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable Lighting
|
// Disable Lighting
|
||||||
// TODO - Is this a good spot for this code?
|
// TODO - Is this a good spot for this code?
|
||||||
if (g_ActiveConfig.bDisableLighting)
|
if (g_ActiveConfig.bDisableLighting)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < xfregs.nNumChans; i++)
|
for (int i = 0; i < xfregs.nNumChans; i++)
|
||||||
{
|
{
|
||||||
xfregs.colChans[i].alpha.enablelighting = false;
|
xfregs.colChans[i].alpha.enablelighting = false;
|
||||||
xfregs.colChans[i].color.enablelighting = false;
|
xfregs.colChans[i].color.enablelighting = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s_prevcomponents = components;
|
s_prevcomponents = components;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,340 +1,340 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
// Common
|
// Common
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "FileUtil.h"
|
#include "FileUtil.h"
|
||||||
|
|
||||||
// VideoCommon
|
// VideoCommon
|
||||||
#include "Profiler.h"
|
#include "Profiler.h"
|
||||||
#include "Statistics.h"
|
#include "Statistics.h"
|
||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
#include "ImageWrite.h"
|
#include "ImageWrite.h"
|
||||||
#include "PixelShaderManager.h"
|
#include "PixelShaderManager.h"
|
||||||
#include "VertexShaderGen.h"
|
#include "VertexShaderGen.h"
|
||||||
|
|
||||||
// OGL
|
// OGL
|
||||||
#include "OGL_Render.h"
|
#include "OGL_Render.h"
|
||||||
#include "OGL_GLUtil.h"
|
#include "OGL_GLUtil.h"
|
||||||
#include "OGL_PixelShaderCache.h"
|
#include "OGL_PixelShaderCache.h"
|
||||||
|
|
||||||
#include "../Main.h"
|
#include "../Main.h"
|
||||||
|
|
||||||
namespace OGL
|
namespace OGL
|
||||||
{
|
{
|
||||||
|
|
||||||
static int s_nMaxPixelInstructions;
|
static int s_nMaxPixelInstructions;
|
||||||
static GLuint s_ColorMatrixProgram = 0;
|
static GLuint s_ColorMatrixProgram = 0;
|
||||||
static GLuint s_DepthMatrixProgram = 0;
|
static GLuint s_DepthMatrixProgram = 0;
|
||||||
PixelShaderCache::PSCache PixelShaderCache::pshaders;
|
PixelShaderCache::PSCache PixelShaderCache::pshaders;
|
||||||
PIXELSHADERUID PixelShaderCache::s_curuid;
|
PIXELSHADERUID PixelShaderCache::s_curuid;
|
||||||
bool PixelShaderCache::s_displayCompileAlert;
|
bool PixelShaderCache::s_displayCompileAlert;
|
||||||
GLuint PixelShaderCache::CurrentShader;
|
GLuint PixelShaderCache::CurrentShader;
|
||||||
bool PixelShaderCache::ShaderEnabled;
|
bool PixelShaderCache::ShaderEnabled;
|
||||||
|
|
||||||
static FRAGMENTSHADER* pShaderLast = NULL;
|
static FRAGMENTSHADER* pShaderLast = NULL;
|
||||||
|
|
||||||
|
|
||||||
void PixelShaderCache::SetPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4)
|
void PixelShaderCache::SetPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4)
|
||||||
{
|
{
|
||||||
float f[4] = { f1, f2, f3, f4 };
|
float f[4] = { f1, f2, f3, f4 };
|
||||||
glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, const_number, f);
|
glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, const_number, f);
|
||||||
//SetPSConstant4fv(const_number, f);
|
//SetPSConstant4fv(const_number, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PixelShaderCache::SetPSConstant4fv(unsigned int const_number, const float *f)
|
void PixelShaderCache::SetPSConstant4fv(unsigned int const_number, const float *f)
|
||||||
{
|
{
|
||||||
glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, const_number, f);
|
glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, const_number, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PixelShaderCache::SetMultiPSConstant4fv(unsigned int const_number, unsigned int count, const float *f)
|
void PixelShaderCache::SetMultiPSConstant4fv(unsigned int const_number, unsigned int count, const float *f)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < count; ++i, f+=4, ++const_number)
|
for (unsigned int i = 0; i < count; ++i, f+=4, ++const_number)
|
||||||
glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, const_number, f);
|
glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, const_number, f);
|
||||||
//SetPSConstant4fv(const_number, f);
|
//SetPSConstant4fv(const_number, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
PixelShaderCache::PixelShaderCache()
|
PixelShaderCache::PixelShaderCache()
|
||||||
{
|
{
|
||||||
glEnable(GL_FRAGMENT_PROGRAM_ARB);
|
glEnable(GL_FRAGMENT_PROGRAM_ARB);
|
||||||
ShaderEnabled = true;
|
ShaderEnabled = true;
|
||||||
CurrentShader = 0;
|
CurrentShader = 0;
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
memset(&last_pixel_shader_uid, 0xFF, sizeof(last_pixel_shader_uid));
|
memset(&last_pixel_shader_uid, 0xFF, sizeof(last_pixel_shader_uid));
|
||||||
|
|
||||||
s_displayCompileAlert = true;
|
s_displayCompileAlert = true;
|
||||||
|
|
||||||
glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB, (GLint *)&s_nMaxPixelInstructions);
|
glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB, (GLint *)&s_nMaxPixelInstructions);
|
||||||
#if CG_VERSION_NUM == 2100
|
#if CG_VERSION_NUM == 2100
|
||||||
if (strstr((const char*)glGetString(GL_VENDOR), "ATI") != NULL)
|
if (strstr((const char*)glGetString(GL_VENDOR), "ATI") != NULL)
|
||||||
{
|
{
|
||||||
s_nMaxPixelInstructions = 4096;
|
s_nMaxPixelInstructions = 4096;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int maxinst, maxattribs;
|
int maxinst, maxattribs;
|
||||||
glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, (GLint *)&maxinst);
|
glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, (GLint *)&maxinst);
|
||||||
glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB, (GLint *)&maxattribs);
|
glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB, (GLint *)&maxattribs);
|
||||||
INFO_LOG(VIDEO, "pixel max_alu=%d, max_inst=%d, max_attrib=%d", s_nMaxPixelInstructions, maxinst, maxattribs);
|
INFO_LOG(VIDEO, "pixel max_alu=%d, max_inst=%d, max_attrib=%d", s_nMaxPixelInstructions, maxinst, maxattribs);
|
||||||
|
|
||||||
char pmatrixprog[1024];
|
char pmatrixprog[1024];
|
||||||
sprintf(pmatrixprog, "!!ARBfp1.0"
|
sprintf(pmatrixprog, "!!ARBfp1.0"
|
||||||
"TEMP R0;\n"
|
"TEMP R0;\n"
|
||||||
"TEMP R1;\n"
|
"TEMP R1;\n"
|
||||||
"TEX R0, fragment.texcoord[0], texture[0], RECT;\n"
|
"TEX R0, fragment.texcoord[0], texture[0], RECT;\n"
|
||||||
"DP4 R1.w, R0, program.env[%d];\n"
|
"DP4 R1.w, R0, program.env[%d];\n"
|
||||||
"DP4 R1.z, R0, program.env[%d];\n"
|
"DP4 R1.z, R0, program.env[%d];\n"
|
||||||
"DP4 R1.x, R0, program.env[%d];\n"
|
"DP4 R1.x, R0, program.env[%d];\n"
|
||||||
"DP4 R1.y, R0, program.env[%d];\n"
|
"DP4 R1.y, R0, program.env[%d];\n"
|
||||||
"ADD result.color, R1, program.env[%d];\n"
|
"ADD result.color, R1, program.env[%d];\n"
|
||||||
"END\n", C_COLORMATRIX+3, C_COLORMATRIX+2, C_COLORMATRIX, C_COLORMATRIX+1, C_COLORMATRIX+4);
|
"END\n", C_COLORMATRIX+3, C_COLORMATRIX+2, C_COLORMATRIX, C_COLORMATRIX+1, C_COLORMATRIX+4);
|
||||||
glGenProgramsARB(1, &s_ColorMatrixProgram);
|
glGenProgramsARB(1, &s_ColorMatrixProgram);
|
||||||
SetCurrentShader(s_ColorMatrixProgram);
|
SetCurrentShader(s_ColorMatrixProgram);
|
||||||
glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(pmatrixprog), pmatrixprog);
|
glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(pmatrixprog), pmatrixprog);
|
||||||
|
|
||||||
GLenum err = GL_REPORT_ERROR();
|
GLenum err = GL_REPORT_ERROR();
|
||||||
if (err != GL_NO_ERROR) {
|
if (err != GL_NO_ERROR) {
|
||||||
ERROR_LOG(VIDEO, "Failed to create color matrix fragment program");
|
ERROR_LOG(VIDEO, "Failed to create color matrix fragment program");
|
||||||
glDeleteProgramsARB(1, &s_ColorMatrixProgram);
|
glDeleteProgramsARB(1, &s_ColorMatrixProgram);
|
||||||
s_ColorMatrixProgram = 0;
|
s_ColorMatrixProgram = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(pmatrixprog, "!!ARBfp1.0"
|
sprintf(pmatrixprog, "!!ARBfp1.0"
|
||||||
"TEMP R0;\n"
|
"TEMP R0;\n"
|
||||||
"TEMP R1;\n"
|
"TEMP R1;\n"
|
||||||
"TEMP R2;\n"
|
"TEMP R2;\n"
|
||||||
"PARAM K0 = { 65535.0, 255.0,1.0,16777215.0};\n"
|
"PARAM K0 = { 65535.0, 255.0,1.0,16777215.0};\n"
|
||||||
"PARAM K1 = { 0.999999940395355224609375, 1.0000000596046483281045155587504,0.0,0.0};\n"
|
"PARAM K1 = { 0.999999940395355224609375, 1.0000000596046483281045155587504,0.0,0.0};\n"
|
||||||
"TEX R2, fragment.texcoord[0], texture[0], RECT;\n"
|
"TEX R2, fragment.texcoord[0], texture[0], RECT;\n"
|
||||||
"MUL R0, R2.x, K1.x;\n"
|
"MUL R0, R2.x, K1.x;\n"
|
||||||
"MUL R0, R0.x, K0;\n"
|
"MUL R0, R0.x, K0;\n"
|
||||||
"FRC R0, R0;\n"
|
"FRC R0, R0;\n"
|
||||||
"MUL R0, R0, K1.y;\n"
|
"MUL R0, R0, K1.y;\n"
|
||||||
"DP4 R1.x, R0, program.env[%d];\n"
|
"DP4 R1.x, R0, program.env[%d];\n"
|
||||||
"DP4 R1.y, R0, program.env[%d];\n"
|
"DP4 R1.y, R0, program.env[%d];\n"
|
||||||
"DP4 R1.z, R0, program.env[%d];\n"
|
"DP4 R1.z, R0, program.env[%d];\n"
|
||||||
"DP4 R1.w, R0, program.env[%d];\n"
|
"DP4 R1.w, R0, program.env[%d];\n"
|
||||||
"ADD result.color, R1, program.env[%d];\n"
|
"ADD result.color, R1, program.env[%d];\n"
|
||||||
"END\n", C_COLORMATRIX, C_COLORMATRIX+1, C_COLORMATRIX+2, C_COLORMATRIX+3, C_COLORMATRIX+4);
|
"END\n", C_COLORMATRIX, C_COLORMATRIX+1, C_COLORMATRIX+2, C_COLORMATRIX+3, C_COLORMATRIX+4);
|
||||||
glGenProgramsARB(1, &s_DepthMatrixProgram);
|
glGenProgramsARB(1, &s_DepthMatrixProgram);
|
||||||
SetCurrentShader(s_DepthMatrixProgram);
|
SetCurrentShader(s_DepthMatrixProgram);
|
||||||
glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(pmatrixprog), pmatrixprog);
|
glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(pmatrixprog), pmatrixprog);
|
||||||
|
|
||||||
err = GL_REPORT_ERROR();
|
err = GL_REPORT_ERROR();
|
||||||
if (err != GL_NO_ERROR) {
|
if (err != GL_NO_ERROR) {
|
||||||
ERROR_LOG(VIDEO, "Failed to create depth matrix fragment program");
|
ERROR_LOG(VIDEO, "Failed to create depth matrix fragment program");
|
||||||
glDeleteProgramsARB(1, &s_DepthMatrixProgram);
|
glDeleteProgramsARB(1, &s_DepthMatrixProgram);
|
||||||
s_DepthMatrixProgram = 0;
|
s_DepthMatrixProgram = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PixelShaderCache::~PixelShaderCache()
|
PixelShaderCache::~PixelShaderCache()
|
||||||
{
|
{
|
||||||
glDeleteProgramsARB(1, &s_ColorMatrixProgram);
|
glDeleteProgramsARB(1, &s_ColorMatrixProgram);
|
||||||
s_ColorMatrixProgram = 0;
|
s_ColorMatrixProgram = 0;
|
||||||
glDeleteProgramsARB(1, &s_DepthMatrixProgram);
|
glDeleteProgramsARB(1, &s_DepthMatrixProgram);
|
||||||
s_DepthMatrixProgram = 0;
|
s_DepthMatrixProgram = 0;
|
||||||
PSCache::iterator iter = pshaders.begin();
|
PSCache::iterator iter = pshaders.begin();
|
||||||
for (; iter != pshaders.end(); iter++)
|
for (; iter != pshaders.end(); iter++)
|
||||||
iter->second.Destroy();
|
iter->second.Destroy();
|
||||||
pshaders.clear();
|
pshaders.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint PixelShaderCache::GetColorMatrixProgram()
|
GLuint PixelShaderCache::GetColorMatrixProgram()
|
||||||
{
|
{
|
||||||
return s_ColorMatrixProgram;
|
return s_ColorMatrixProgram;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint PixelShaderCache::GetDepthMatrixProgram()
|
GLuint PixelShaderCache::GetDepthMatrixProgram()
|
||||||
{
|
{
|
||||||
return s_DepthMatrixProgram;
|
return s_DepthMatrixProgram;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PixelShaderCache::SetShader(bool dstAlphaEnable)
|
bool PixelShaderCache::SetShader(bool dstAlphaEnable)
|
||||||
{
|
{
|
||||||
const FRAGMENTSHADER* const ps = GetShader(dstAlphaEnable);
|
const FRAGMENTSHADER* const ps = GetShader(dstAlphaEnable);
|
||||||
if (ps)
|
if (ps)
|
||||||
{
|
{
|
||||||
SetCurrentShader(ps->glprogid);
|
SetCurrentShader(ps->glprogid);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
FRAGMENTSHADER* PixelShaderCache::GetShader(bool dstAlphaEnable)
|
FRAGMENTSHADER* PixelShaderCache::GetShader(bool dstAlphaEnable)
|
||||||
{
|
{
|
||||||
DVSTARTPROFILE();
|
DVSTARTPROFILE();
|
||||||
PIXELSHADERUID uid;
|
PIXELSHADERUID uid;
|
||||||
GetPixelShaderId(&uid, dstAlphaEnable ? 1 : 0);
|
GetPixelShaderId(&uid, dstAlphaEnable ? 1 : 0);
|
||||||
if (uid == last_pixel_shader_uid && pshaders[uid].frameCount == frameCount)
|
if (uid == last_pixel_shader_uid && pshaders[uid].frameCount == frameCount)
|
||||||
{
|
{
|
||||||
return pShaderLast;
|
return pShaderLast;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(&last_pixel_shader_uid, &uid, sizeof(PIXELSHADERUID));
|
memcpy(&last_pixel_shader_uid, &uid, sizeof(PIXELSHADERUID));
|
||||||
|
|
||||||
PSCache::iterator iter = pshaders.find(uid);
|
PSCache::iterator iter = pshaders.find(uid);
|
||||||
|
|
||||||
if (iter != pshaders.end()) {
|
if (iter != pshaders.end()) {
|
||||||
iter->second.frameCount = frameCount;
|
iter->second.frameCount = frameCount;
|
||||||
PSCacheEntry &entry = iter->second;
|
PSCacheEntry &entry = iter->second;
|
||||||
if (&entry.shader != pShaderLast)
|
if (&entry.shader != pShaderLast)
|
||||||
{
|
{
|
||||||
pShaderLast = &entry.shader;
|
pShaderLast = &entry.shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pShaderLast;
|
return pShaderLast;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Make an entry in the table
|
//Make an entry in the table
|
||||||
PSCacheEntry& newentry = pshaders[uid];
|
PSCacheEntry& newentry = pshaders[uid];
|
||||||
newentry.frameCount = frameCount;
|
newentry.frameCount = frameCount;
|
||||||
pShaderLast = &newentry.shader;
|
pShaderLast = &newentry.shader;
|
||||||
const char *code = GeneratePixelShaderCode(dstAlphaEnable,API_OPENGL);
|
const char *code = GeneratePixelShaderCode(dstAlphaEnable,API_OPENGL);
|
||||||
|
|
||||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||||
if (g_ActiveConfig.iLog & CONF_SAVESHADERS && code) {
|
if (g_ActiveConfig.iLog & CONF_SAVESHADERS && code) {
|
||||||
static int counter = 0;
|
static int counter = 0;
|
||||||
char szTemp[MAX_PATH];
|
char szTemp[MAX_PATH];
|
||||||
sprintf(szTemp, "%sps_%04i.txt", File::GetUserPath(D_DUMP_IDX), counter++);
|
sprintf(szTemp, "%sps_%04i.txt", File::GetUserPath(D_DUMP_IDX), counter++);
|
||||||
|
|
||||||
SaveData(szTemp, code);
|
SaveData(szTemp, code);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// printf("Compiling pixel shader. size = %i\n", strlen(code));
|
// printf("Compiling pixel shader. size = %i\n", strlen(code));
|
||||||
if (!code || !CompilePixelShader(newentry.shader, code)) {
|
if (!code || !CompilePixelShader(newentry.shader, code)) {
|
||||||
ERROR_LOG(VIDEO, "failed to create pixel shader");
|
ERROR_LOG(VIDEO, "failed to create pixel shader");
|
||||||
static int counter = 0;
|
static int counter = 0;
|
||||||
char szTemp[MAX_PATH];
|
char szTemp[MAX_PATH];
|
||||||
sprintf(szTemp, "%sBADps_%04i.txt", File::GetUserPath(D_DUMP_IDX), counter++);
|
sprintf(szTemp, "%sBADps_%04i.txt", File::GetUserPath(D_DUMP_IDX), counter++);
|
||||||
SaveData(szTemp, code);
|
SaveData(szTemp, code);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
INCSTAT(stats.numPixelShadersCreated);
|
INCSTAT(stats.numPixelShadersCreated);
|
||||||
SETSTAT(stats.numPixelShadersAlive, pshaders.size());
|
SETSTAT(stats.numPixelShadersAlive, pshaders.size());
|
||||||
return pShaderLast;
|
return pShaderLast;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PixelShaderCache::CompilePixelShader(FRAGMENTSHADER& ps, const char* pstrprogram)
|
bool PixelShaderCache::CompilePixelShader(FRAGMENTSHADER& ps, const char* pstrprogram)
|
||||||
{
|
{
|
||||||
GLenum err = GL_REPORT_ERROR();
|
GLenum err = GL_REPORT_ERROR();
|
||||||
if (err != GL_NO_ERROR)
|
if (err != GL_NO_ERROR)
|
||||||
{
|
{
|
||||||
ERROR_LOG(VIDEO, "glError %08x before PS!", err);
|
ERROR_LOG(VIDEO, "glError %08x before PS!", err);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined HAVE_CG && HAVE_CG
|
#if defined HAVE_CG && HAVE_CG
|
||||||
char stropt[128];
|
char stropt[128];
|
||||||
sprintf(stropt, "MaxLocalParams=32,NumInstructionSlots=%d", s_nMaxPixelInstructions);
|
sprintf(stropt, "MaxLocalParams=32,NumInstructionSlots=%d", s_nMaxPixelInstructions);
|
||||||
const char *opts[] = {"-profileopts", stropt, "-O2", "-q", NULL};
|
const char *opts[] = {"-profileopts", stropt, "-O2", "-q", NULL};
|
||||||
CGprogram tempprog = cgCreateProgram(g_cgcontext, CG_SOURCE, pstrprogram, g_cgfProf, "main", opts);
|
CGprogram tempprog = cgCreateProgram(g_cgcontext, CG_SOURCE, pstrprogram, g_cgfProf, "main", opts);
|
||||||
|
|
||||||
// handle errors
|
// handle errors
|
||||||
if (!cgIsProgram(tempprog)) {
|
if (!cgIsProgram(tempprog)) {
|
||||||
cgDestroyProgram(tempprog);
|
cgDestroyProgram(tempprog);
|
||||||
ERROR_LOG(VIDEO, "Failed to compile ps %s:", cgGetLastListing(g_cgcontext));
|
ERROR_LOG(VIDEO, "Failed to compile ps %s:", cgGetLastListing(g_cgcontext));
|
||||||
ERROR_LOG(VIDEO, pstrprogram);
|
ERROR_LOG(VIDEO, pstrprogram);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle warnings
|
// handle warnings
|
||||||
if (cgGetError() != CG_NO_ERROR)
|
if (cgGetError() != CG_NO_ERROR)
|
||||||
{
|
{
|
||||||
WARN_LOG(VIDEO, "Warnings on compile ps %s:", cgGetLastListing(g_cgcontext));
|
WARN_LOG(VIDEO, "Warnings on compile ps %s:", cgGetLastListing(g_cgcontext));
|
||||||
WARN_LOG(VIDEO, pstrprogram);
|
WARN_LOG(VIDEO, pstrprogram);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This looks evil - we modify the program through the const char * we got from cgGetProgramString!
|
// This looks evil - we modify the program through the const char * we got from cgGetProgramString!
|
||||||
// It SHOULD not have any nasty side effects though - but you never know...
|
// It SHOULD not have any nasty side effects though - but you never know...
|
||||||
char *pcompiledprog = (char*)cgGetProgramString(tempprog, CG_COMPILED_PROGRAM);
|
char *pcompiledprog = (char*)cgGetProgramString(tempprog, CG_COMPILED_PROGRAM);
|
||||||
char *plocal = strstr(pcompiledprog, "program.local");
|
char *plocal = strstr(pcompiledprog, "program.local");
|
||||||
while (plocal != NULL) {
|
while (plocal != NULL) {
|
||||||
const char *penv = " program.env";
|
const char *penv = " program.env";
|
||||||
memcpy(plocal, penv, 13);
|
memcpy(plocal, penv, 13);
|
||||||
plocal = strstr(plocal+13, "program.local");
|
plocal = strstr(plocal+13, "program.local");
|
||||||
}
|
}
|
||||||
|
|
||||||
glGenProgramsARB(1, &ps.glprogid);
|
glGenProgramsARB(1, &ps.glprogid);
|
||||||
SetCurrentShader(ps.glprogid);
|
SetCurrentShader(ps.glprogid);
|
||||||
glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(pcompiledprog), pcompiledprog);
|
glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(pcompiledprog), pcompiledprog);
|
||||||
|
|
||||||
err = GL_REPORT_ERROR();
|
err = GL_REPORT_ERROR();
|
||||||
if (err != GL_NO_ERROR)
|
if (err != GL_NO_ERROR)
|
||||||
{
|
{
|
||||||
GLint error_pos, native_limit;
|
GLint error_pos, native_limit;
|
||||||
glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &error_pos);
|
glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &error_pos);
|
||||||
glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB, &native_limit);
|
glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB, &native_limit);
|
||||||
// Error occur
|
// Error occur
|
||||||
if (error_pos != -1) {
|
if (error_pos != -1) {
|
||||||
const char *program_error = (const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB);
|
const char *program_error = (const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB);
|
||||||
char line[256];
|
char line[256];
|
||||||
strncpy(line, (const char *)pcompiledprog + error_pos, 255);
|
strncpy(line, (const char *)pcompiledprog + error_pos, 255);
|
||||||
line[255] = 0;
|
line[255] = 0;
|
||||||
ERROR_LOG(VIDEO, "Error at %i: %s", error_pos, program_error);
|
ERROR_LOG(VIDEO, "Error at %i: %s", error_pos, program_error);
|
||||||
ERROR_LOG(VIDEO, "Line dump: \n%s", line);
|
ERROR_LOG(VIDEO, "Line dump: \n%s", line);
|
||||||
} else if (native_limit != -1) {
|
} else if (native_limit != -1) {
|
||||||
ERROR_LOG(VIDEO, "Hit limit? %i", native_limit);
|
ERROR_LOG(VIDEO, "Hit limit? %i", native_limit);
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
ERROR_LOG(VIDEO, pstrprogram);
|
ERROR_LOG(VIDEO, pstrprogram);
|
||||||
ERROR_LOG(VIDEO, pcompiledprog);
|
ERROR_LOG(VIDEO, pcompiledprog);
|
||||||
}
|
}
|
||||||
|
|
||||||
cgDestroyProgram(tempprog);
|
cgDestroyProgram(tempprog);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||||
ps.strprog = pstrprogram;
|
ps.strprog = pstrprogram;
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Disable Fragment programs and reset the selected Program
|
//Disable Fragment programs and reset the selected Program
|
||||||
void PixelShaderCache::DisableShader()
|
void PixelShaderCache::DisableShader()
|
||||||
{
|
{
|
||||||
if(ShaderEnabled)
|
if(ShaderEnabled)
|
||||||
{
|
{
|
||||||
glDisable(GL_FRAGMENT_PROGRAM_ARB);
|
glDisable(GL_FRAGMENT_PROGRAM_ARB);
|
||||||
ShaderEnabled = false;
|
ShaderEnabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//bind a program if is diferent from the binded oone
|
//bind a program if is diferent from the binded oone
|
||||||
void PixelShaderCache::SetCurrentShader(GLuint Shader)
|
void PixelShaderCache::SetCurrentShader(GLuint Shader)
|
||||||
{
|
{
|
||||||
if(!ShaderEnabled)
|
if(!ShaderEnabled)
|
||||||
{
|
{
|
||||||
glEnable(GL_FRAGMENT_PROGRAM_ARB);
|
glEnable(GL_FRAGMENT_PROGRAM_ARB);
|
||||||
ShaderEnabled = true;
|
ShaderEnabled = true;
|
||||||
}
|
}
|
||||||
if(CurrentShader != Shader)
|
if(CurrentShader != Shader)
|
||||||
{
|
{
|
||||||
if(Shader != 0)
|
if(Shader != 0)
|
||||||
CurrentShader = Shader;
|
CurrentShader = Shader;
|
||||||
glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, CurrentShader);
|
glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, CurrentShader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,96 +1,96 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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/
|
||||||
|
|
||||||
#ifndef _OGL_PIXELSHADERCACHE_H_
|
#ifndef _OGL_PIXELSHADERCACHE_H_
|
||||||
#define _OGL_PIXELSHADERCACHE_H_
|
#define _OGL_PIXELSHADERCACHE_H_
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
// VideoCommon
|
// VideoCommon
|
||||||
#include "BPMemory.h"
|
#include "BPMemory.h"
|
||||||
#include "PixelShaderGen.h"
|
#include "PixelShaderGen.h"
|
||||||
|
|
||||||
#include "../PixelShaderCache.h"
|
#include "../PixelShaderCache.h"
|
||||||
|
|
||||||
namespace OGL
|
namespace OGL
|
||||||
{
|
{
|
||||||
|
|
||||||
struct FRAGMENTSHADER
|
struct FRAGMENTSHADER
|
||||||
{
|
{
|
||||||
FRAGMENTSHADER() : glprogid(0) { }
|
FRAGMENTSHADER() : glprogid(0) { }
|
||||||
void Destroy()
|
void Destroy()
|
||||||
{
|
{
|
||||||
if (glprogid)
|
if (glprogid)
|
||||||
{
|
{
|
||||||
glDeleteProgramsARB(1, &glprogid);
|
glDeleteProgramsARB(1, &glprogid);
|
||||||
glprogid = 0;
|
glprogid = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GLuint glprogid; // opengl program id
|
GLuint glprogid; // opengl program id
|
||||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||||
std::string strprog;
|
std::string strprog;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
class PixelShaderCache : public ::PixelShaderCacheBase
|
class PixelShaderCache : public ::PixelShaderCacheBase
|
||||||
{
|
{
|
||||||
struct PSCacheEntry
|
struct PSCacheEntry
|
||||||
{
|
{
|
||||||
FRAGMENTSHADER shader;
|
FRAGMENTSHADER shader;
|
||||||
int frameCount;
|
int frameCount;
|
||||||
|
|
||||||
PSCacheEntry() : frameCount(0) {}
|
PSCacheEntry() : frameCount(0) {}
|
||||||
void Destroy()
|
void Destroy()
|
||||||
{
|
{
|
||||||
shader.Destroy();
|
shader.Destroy();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<PIXELSHADERUID, PSCacheEntry> PSCache;
|
typedef std::map<PIXELSHADERUID, PSCacheEntry> PSCache;
|
||||||
|
|
||||||
static PSCache pshaders;
|
static PSCache pshaders;
|
||||||
static PIXELSHADERUID s_curuid; // the current pixel shader uid (progressively changed as memory is written)
|
static PIXELSHADERUID s_curuid; // the current pixel shader uid (progressively changed as memory is written)
|
||||||
static bool s_displayCompileAlert;
|
static bool s_displayCompileAlert;
|
||||||
static GLuint CurrentShader;
|
static GLuint CurrentShader;
|
||||||
static bool ShaderEnabled;
|
static bool ShaderEnabled;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PixelShaderCache();
|
PixelShaderCache();
|
||||||
~PixelShaderCache();
|
~PixelShaderCache();
|
||||||
|
|
||||||
static FRAGMENTSHADER* GetShader(bool dstAlphaEnable);
|
static FRAGMENTSHADER* GetShader(bool dstAlphaEnable);
|
||||||
static bool CompilePixelShader(FRAGMENTSHADER& ps, const char* pstrprogram);
|
static bool CompilePixelShader(FRAGMENTSHADER& ps, const char* pstrprogram);
|
||||||
|
|
||||||
static GLuint GetColorMatrixProgram();
|
static GLuint GetColorMatrixProgram();
|
||||||
static GLuint GetDepthMatrixProgram();
|
static GLuint GetDepthMatrixProgram();
|
||||||
|
|
||||||
bool SetShader(bool dstAlphaEnable);
|
bool SetShader(bool dstAlphaEnable);
|
||||||
|
|
||||||
static void SetCurrentShader(GLuint Shader);
|
static void SetCurrentShader(GLuint Shader);
|
||||||
static void DisableShader();
|
static void DisableShader();
|
||||||
|
|
||||||
void Clear() {}
|
void Clear() {}
|
||||||
|
|
||||||
void SetPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4);
|
void SetPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4);
|
||||||
void SetPSConstant4fv(unsigned int const_number, const float *f);
|
void SetPSConstant4fv(unsigned int const_number, const float *f);
|
||||||
void SetMultiPSConstant4fv(unsigned int const_number, unsigned int count, const float *f);
|
void SetMultiPSConstant4fv(unsigned int const_number, unsigned int count, const float *f);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // _PIXELSHADERCACHE_H_
|
#endif // _PIXELSHADERCACHE_H_
|
||||||
|
|||||||
@@ -1,97 +1,97 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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/
|
||||||
|
|
||||||
// Common
|
// Common
|
||||||
#include "FileUtil.h"
|
#include "FileUtil.h"
|
||||||
|
|
||||||
// VideoCommon
|
// VideoCommon
|
||||||
#include "VideoCommon.h"
|
#include "VideoCommon.h"
|
||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
|
|
||||||
// OGL
|
// OGL
|
||||||
#include "OGL_GLUtil.h"
|
#include "OGL_GLUtil.h"
|
||||||
#include "OGL_PostProcessing.h"
|
#include "OGL_PostProcessing.h"
|
||||||
#include "OGL_PixelShaderCache.h"
|
#include "OGL_PixelShaderCache.h"
|
||||||
|
|
||||||
namespace OGL
|
namespace OGL
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace PostProcessing
|
namespace PostProcessing
|
||||||
{
|
{
|
||||||
|
|
||||||
static std::string s_currentShader;
|
static std::string s_currentShader;
|
||||||
static FRAGMENTSHADER s_shader;
|
static FRAGMENTSHADER s_shader;
|
||||||
|
|
||||||
void Init()
|
void Init()
|
||||||
{
|
{
|
||||||
s_currentShader = "";
|
s_currentShader = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shutdown()
|
void Shutdown()
|
||||||
{
|
{
|
||||||
s_shader.Destroy();
|
s_shader.Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReloadShader()
|
void ReloadShader()
|
||||||
{
|
{
|
||||||
s_currentShader = "";
|
s_currentShader = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ApplyShader()
|
bool ApplyShader()
|
||||||
{
|
{
|
||||||
if (s_currentShader != std::string(File::GetUserPath(D_SHADERS_IDX)) + g_ActiveConfig.sPostProcessingShader + ".txt")
|
if (s_currentShader != std::string(File::GetUserPath(D_SHADERS_IDX)) + g_ActiveConfig.sPostProcessingShader + ".txt")
|
||||||
{
|
{
|
||||||
// Set immediately to prevent endless recompiles on failure.
|
// Set immediately to prevent endless recompiles on failure.
|
||||||
if (!g_ActiveConfig.sPostProcessingShader.empty())
|
if (!g_ActiveConfig.sPostProcessingShader.empty())
|
||||||
s_currentShader = std::string(File::GetUserPath(D_SHADERS_IDX)) + g_ActiveConfig.sPostProcessingShader + ".txt";
|
s_currentShader = std::string(File::GetUserPath(D_SHADERS_IDX)) + g_ActiveConfig.sPostProcessingShader + ".txt";
|
||||||
else
|
else
|
||||||
s_currentShader.clear();
|
s_currentShader.clear();
|
||||||
|
|
||||||
s_shader.Destroy();
|
s_shader.Destroy();
|
||||||
|
|
||||||
if (!s_currentShader.empty())
|
if (!s_currentShader.empty())
|
||||||
{
|
{
|
||||||
std::string code;
|
std::string code;
|
||||||
if (File::ReadFileToString(true, s_currentShader.c_str(), code))
|
if (File::ReadFileToString(true, s_currentShader.c_str(), code))
|
||||||
{
|
{
|
||||||
if (!PixelShaderCache::CompilePixelShader(s_shader, code.c_str()))
|
if (!PixelShaderCache::CompilePixelShader(s_shader, code.c_str()))
|
||||||
{
|
{
|
||||||
ERROR_LOG(VIDEO, "Failed to compile post-processing shader %s", s_currentShader.c_str());
|
ERROR_LOG(VIDEO, "Failed to compile post-processing shader %s", s_currentShader.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ERROR_LOG(VIDEO, "Failed to load post-processing shader %s - does not exist?", s_currentShader.c_str());
|
ERROR_LOG(VIDEO, "Failed to load post-processing shader %s - does not exist?", s_currentShader.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s_shader.glprogid != 0)
|
if (s_shader.glprogid != 0)
|
||||||
{
|
{
|
||||||
PixelShaderCache::SetCurrentShader(s_shader.glprogid);
|
PixelShaderCache::SetCurrentShader(s_shader.glprogid);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PixelShaderCache::DisableShader();
|
PixelShaderCache::DisableShader();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,42 +1,42 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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/
|
||||||
|
|
||||||
#ifndef _OGL_POSTPROCESSING_H_
|
#ifndef _OGL_POSTPROCESSING_H_
|
||||||
#define _OGL_POSTPROCESSING_H_
|
#define _OGL_POSTPROCESSING_H_
|
||||||
|
|
||||||
#include "VideoCommon.h"
|
#include "VideoCommon.h"
|
||||||
|
|
||||||
#include "OGL_GLUtil.h"
|
#include "OGL_GLUtil.h"
|
||||||
|
|
||||||
namespace OGL
|
namespace OGL
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace PostProcessing
|
namespace PostProcessing
|
||||||
{
|
{
|
||||||
|
|
||||||
void Init();
|
void Init();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
|
||||||
void ReloadShader();
|
void ReloadShader();
|
||||||
// Returns false if no shader was applied.
|
// Returns false if no shader was applied.
|
||||||
bool ApplyShader();
|
bool ApplyShader();
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // _POSTPROCESSING_H_
|
#endif // _POSTPROCESSING_H_
|
||||||
|
|||||||
@@ -1,226 +1,226 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "OGL_GLUtil.h"
|
#include "OGL_GLUtil.h"
|
||||||
#include "OGL_RasterFont.h"
|
#include "OGL_RasterFont.h"
|
||||||
// globals
|
// globals
|
||||||
|
|
||||||
namespace OGL
|
namespace OGL
|
||||||
{
|
{
|
||||||
|
|
||||||
GLubyte rasters[][13] = {
|
GLubyte rasters[][13] = {
|
||||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||||
{0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
|
{0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
|
||||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36},
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36},
|
||||||
{0x00, 0x00, 0x00, 0x66, 0x66, 0xff, 0x66, 0x66, 0xff, 0x66, 0x66, 0x00, 0x00},
|
{0x00, 0x00, 0x00, 0x66, 0x66, 0xff, 0x66, 0x66, 0xff, 0x66, 0x66, 0x00, 0x00},
|
||||||
{0x00, 0x00, 0x18, 0x7e, 0xff, 0x1b, 0x1f, 0x7e, 0xf8, 0xd8, 0xff, 0x7e, 0x18},
|
{0x00, 0x00, 0x18, 0x7e, 0xff, 0x1b, 0x1f, 0x7e, 0xf8, 0xd8, 0xff, 0x7e, 0x18},
|
||||||
{0x00, 0x00, 0x0e, 0x1b, 0xdb, 0x6e, 0x30, 0x18, 0x0c, 0x76, 0xdb, 0xd8, 0x70},
|
{0x00, 0x00, 0x0e, 0x1b, 0xdb, 0x6e, 0x30, 0x18, 0x0c, 0x76, 0xdb, 0xd8, 0x70},
|
||||||
{0x00, 0x00, 0x7f, 0xc6, 0xcf, 0xd8, 0x70, 0x70, 0xd8, 0xcc, 0xcc, 0x6c, 0x38},
|
{0x00, 0x00, 0x7f, 0xc6, 0xcf, 0xd8, 0x70, 0x70, 0xd8, 0xcc, 0xcc, 0x6c, 0x38},
|
||||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x1c, 0x0c, 0x0e},
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x1c, 0x0c, 0x0e},
|
||||||
{0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c},
|
{0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c},
|
||||||
{0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30},
|
{0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30},
|
||||||
{0x00, 0x00, 0x00, 0x00, 0x99, 0x5a, 0x3c, 0xff, 0x3c, 0x5a, 0x99, 0x00, 0x00},
|
{0x00, 0x00, 0x00, 0x00, 0x99, 0x5a, 0x3c, 0xff, 0x3c, 0x5a, 0x99, 0x00, 0x00},
|
||||||
{0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18, 0x00, 0x00},
|
{0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18, 0x00, 0x00},
|
||||||
{0x00, 0x00, 0x30, 0x18, 0x1c, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
{0x00, 0x00, 0x30, 0x18, 0x1c, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00},
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||||
{0x00, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
{0x00, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||||
{0x00, 0x60, 0x60, 0x30, 0x30, 0x18, 0x18, 0x0c, 0x0c, 0x06, 0x06, 0x03, 0x03},
|
{0x00, 0x60, 0x60, 0x30, 0x30, 0x18, 0x18, 0x0c, 0x0c, 0x06, 0x06, 0x03, 0x03},
|
||||||
{0x00, 0x00, 0x3c, 0x66, 0xc3, 0xe3, 0xf3, 0xdb, 0xcf, 0xc7, 0xc3, 0x66, 0x3c},
|
{0x00, 0x00, 0x3c, 0x66, 0xc3, 0xe3, 0xf3, 0xdb, 0xcf, 0xc7, 0xc3, 0x66, 0x3c},
|
||||||
{0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x38, 0x18},
|
{0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x38, 0x18},
|
||||||
{0x00, 0x00, 0xff, 0xc0, 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0xe7, 0x7e},
|
{0x00, 0x00, 0xff, 0xc0, 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0xe7, 0x7e},
|
||||||
{0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x07, 0x7e, 0x07, 0x03, 0x03, 0xe7, 0x7e},
|
{0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x07, 0x7e, 0x07, 0x03, 0x03, 0xe7, 0x7e},
|
||||||
{0x00, 0x00, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xff, 0xcc, 0x6c, 0x3c, 0x1c, 0x0c},
|
{0x00, 0x00, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xff, 0xcc, 0x6c, 0x3c, 0x1c, 0x0c},
|
||||||
{0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x07, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0xff},
|
{0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x07, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0xff},
|
||||||
{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xc7, 0xfe, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e},
|
{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xc7, 0xfe, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e},
|
||||||
{0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x03, 0x03, 0xff},
|
{0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x03, 0x03, 0xff},
|
||||||
{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xe7, 0x7e, 0xe7, 0xc3, 0xc3, 0xe7, 0x7e},
|
{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xe7, 0x7e, 0xe7, 0xc3, 0xc3, 0xe7, 0x7e},
|
||||||
{0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x03, 0x7f, 0xe7, 0xc3, 0xc3, 0xe7, 0x7e},
|
{0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x03, 0x7f, 0xe7, 0xc3, 0xc3, 0xe7, 0x7e},
|
||||||
{0x00, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00},
|
{0x00, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00},
|
||||||
{0x00, 0x00, 0x30, 0x18, 0x1c, 0x1c, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x00},
|
{0x00, 0x00, 0x30, 0x18, 0x1c, 0x1c, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x00},
|
||||||
{0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06},
|
{0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06},
|
||||||
{0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00},
|
{0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00},
|
||||||
{0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60},
|
{0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60},
|
||||||
{0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x18, 0x0c, 0x06, 0x03, 0xc3, 0xc3, 0x7e},
|
{0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x18, 0x0c, 0x06, 0x03, 0xc3, 0xc3, 0x7e},
|
||||||
{0x00, 0x00, 0x3f, 0x60, 0xcf, 0xdb, 0xd3, 0xdd, 0xc3, 0x7e, 0x00, 0x00, 0x00},
|
{0x00, 0x00, 0x3f, 0x60, 0xcf, 0xdb, 0xd3, 0xdd, 0xc3, 0x7e, 0x00, 0x00, 0x00},
|
||||||
{0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xff, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18},
|
{0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xff, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18},
|
||||||
{0x00, 0x00, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe},
|
{0x00, 0x00, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe},
|
||||||
{0x00, 0x00, 0x7e, 0xe7, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e},
|
{0x00, 0x00, 0x7e, 0xe7, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e},
|
||||||
{0x00, 0x00, 0xfc, 0xce, 0xc7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc7, 0xce, 0xfc},
|
{0x00, 0x00, 0xfc, 0xce, 0xc7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc7, 0xce, 0xfc},
|
||||||
{0x00, 0x00, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xff},
|
{0x00, 0x00, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xff},
|
||||||
{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xff},
|
{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xff},
|
||||||
{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xcf, 0xc0, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e},
|
{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xcf, 0xc0, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e},
|
||||||
{0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xff, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3},
|
{0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xff, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3},
|
||||||
{0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e},
|
{0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e},
|
||||||
{0x00, 0x00, 0x7c, 0xee, 0xc6, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06},
|
{0x00, 0x00, 0x7c, 0xee, 0xc6, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06},
|
||||||
{0x00, 0x00, 0xc3, 0xc6, 0xcc, 0xd8, 0xf0, 0xe0, 0xf0, 0xd8, 0xcc, 0xc6, 0xc3},
|
{0x00, 0x00, 0xc3, 0xc6, 0xcc, 0xd8, 0xf0, 0xe0, 0xf0, 0xd8, 0xcc, 0xc6, 0xc3},
|
||||||
{0x00, 0x00, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0},
|
{0x00, 0x00, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0},
|
||||||
{0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xff, 0xff, 0xe7, 0xc3},
|
{0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xff, 0xff, 0xe7, 0xc3},
|
||||||
{0x00, 0x00, 0xc7, 0xc7, 0xcf, 0xcf, 0xdf, 0xdb, 0xfb, 0xf3, 0xf3, 0xe3, 0xe3},
|
{0x00, 0x00, 0xc7, 0xc7, 0xcf, 0xcf, 0xdf, 0xdb, 0xfb, 0xf3, 0xf3, 0xe3, 0xe3},
|
||||||
{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xe7, 0x7e},
|
{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xe7, 0x7e},
|
||||||
{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe},
|
{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe},
|
||||||
{0x00, 0x00, 0x3f, 0x6e, 0xdf, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c},
|
{0x00, 0x00, 0x3f, 0x6e, 0xdf, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c},
|
||||||
{0x00, 0x00, 0xc3, 0xc6, 0xcc, 0xd8, 0xf0, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe},
|
{0x00, 0x00, 0xc3, 0xc6, 0xcc, 0xd8, 0xf0, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe},
|
||||||
{0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x07, 0x7e, 0xe0, 0xc0, 0xc0, 0xe7, 0x7e},
|
{0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x07, 0x7e, 0xe0, 0xc0, 0xc0, 0xe7, 0x7e},
|
||||||
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff},
|
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff},
|
||||||
{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3},
|
{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3},
|
||||||
{0x00, 0x00, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3},
|
{0x00, 0x00, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3},
|
||||||
{0x00, 0x00, 0xc3, 0xe7, 0xff, 0xff, 0xdb, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3},
|
{0x00, 0x00, 0xc3, 0xe7, 0xff, 0xff, 0xdb, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3},
|
||||||
{0x00, 0x00, 0xc3, 0x66, 0x66, 0x3c, 0x3c, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3},
|
{0x00, 0x00, 0xc3, 0x66, 0x66, 0x3c, 0x3c, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3},
|
||||||
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3},
|
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3},
|
||||||
{0x00, 0x00, 0xff, 0xc0, 0xc0, 0x60, 0x30, 0x7e, 0x0c, 0x06, 0x03, 0x03, 0xff},
|
{0x00, 0x00, 0xff, 0xc0, 0xc0, 0x60, 0x30, 0x7e, 0x0c, 0x06, 0x03, 0x03, 0xff},
|
||||||
{0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c},
|
{0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c},
|
||||||
{0x00, 0x03, 0x03, 0x06, 0x06, 0x0c, 0x0c, 0x18, 0x18, 0x30, 0x30, 0x60, 0x60},
|
{0x00, 0x03, 0x03, 0x06, 0x06, 0x0c, 0x0c, 0x18, 0x18, 0x30, 0x30, 0x60, 0x60},
|
||||||
{0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c},
|
{0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c},
|
||||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18},
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18},
|
||||||
{0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
{0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x30, 0x70},
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x30, 0x70},
|
||||||
{0x00, 0x00, 0x7f, 0xc3, 0xc3, 0x7f, 0x03, 0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00},
|
{0x00, 0x00, 0x7f, 0xc3, 0xc3, 0x7f, 0x03, 0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00},
|
||||||
{0x00, 0x00, 0xfe, 0xc3, 0xc3, 0xc3, 0xc3, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0},
|
{0x00, 0x00, 0xfe, 0xc3, 0xc3, 0xc3, 0xc3, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0},
|
||||||
{0x00, 0x00, 0x7e, 0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00},
|
{0x00, 0x00, 0x7e, 0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00},
|
||||||
{0x00, 0x00, 0x7f, 0xc3, 0xc3, 0xc3, 0xc3, 0x7f, 0x03, 0x03, 0x03, 0x03, 0x03},
|
{0x00, 0x00, 0x7f, 0xc3, 0xc3, 0xc3, 0xc3, 0x7f, 0x03, 0x03, 0x03, 0x03, 0x03},
|
||||||
{0x00, 0x00, 0x7f, 0xc0, 0xc0, 0xfe, 0xc3, 0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00},
|
{0x00, 0x00, 0x7f, 0xc0, 0xc0, 0xfe, 0xc3, 0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00},
|
||||||
{0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x33, 0x1e},
|
{0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x33, 0x1e},
|
||||||
{0x7e, 0xc3, 0x03, 0x03, 0x7f, 0xc3, 0xc3, 0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00},
|
{0x7e, 0xc3, 0x03, 0x03, 0x7f, 0xc3, 0xc3, 0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00},
|
||||||
{0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0},
|
{0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0},
|
||||||
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x00},
|
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x00},
|
||||||
{0x38, 0x6c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x00, 0x00, 0x0c, 0x00},
|
{0x38, 0x6c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x00, 0x00, 0x0c, 0x00},
|
||||||
{0x00, 0x00, 0xc6, 0xcc, 0xf8, 0xf0, 0xd8, 0xcc, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0},
|
{0x00, 0x00, 0xc6, 0xcc, 0xf8, 0xf0, 0xd8, 0xcc, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0},
|
||||||
{0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78},
|
{0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78},
|
||||||
{0x00, 0x00, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xfe, 0x00, 0x00, 0x00, 0x00},
|
{0x00, 0x00, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xfe, 0x00, 0x00, 0x00, 0x00},
|
||||||
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xfc, 0x00, 0x00, 0x00, 0x00},
|
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xfc, 0x00, 0x00, 0x00, 0x00},
|
||||||
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
|
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
|
||||||
{0xc0, 0xc0, 0xc0, 0xfe, 0xc3, 0xc3, 0xc3, 0xc3, 0xfe, 0x00, 0x00, 0x00, 0x00},
|
{0xc0, 0xc0, 0xc0, 0xfe, 0xc3, 0xc3, 0xc3, 0xc3, 0xfe, 0x00, 0x00, 0x00, 0x00},
|
||||||
{0x03, 0x03, 0x03, 0x7f, 0xc3, 0xc3, 0xc3, 0xc3, 0x7f, 0x00, 0x00, 0x00, 0x00},
|
{0x03, 0x03, 0x03, 0x7f, 0xc3, 0xc3, 0xc3, 0xc3, 0x7f, 0x00, 0x00, 0x00, 0x00},
|
||||||
{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xe0, 0xfe, 0x00, 0x00, 0x00, 0x00},
|
{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xe0, 0xfe, 0x00, 0x00, 0x00, 0x00},
|
||||||
{0x00, 0x00, 0xfe, 0x03, 0x03, 0x7e, 0xc0, 0xc0, 0x7f, 0x00, 0x00, 0x00, 0x00},
|
{0x00, 0x00, 0xfe, 0x03, 0x03, 0x7e, 0xc0, 0xc0, 0x7f, 0x00, 0x00, 0x00, 0x00},
|
||||||
{0x00, 0x00, 0x1c, 0x36, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x00},
|
{0x00, 0x00, 0x1c, 0x36, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x00},
|
||||||
{0x00, 0x00, 0x7e, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
|
{0x00, 0x00, 0x7e, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
|
||||||
{0x00, 0x00, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00},
|
{0x00, 0x00, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00},
|
||||||
{0x00, 0x00, 0xc3, 0xe7, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00},
|
{0x00, 0x00, 0xc3, 0xe7, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00},
|
||||||
{0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00},
|
{0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00},
|
||||||
{0xc0, 0x60, 0x60, 0x30, 0x18, 0x3c, 0x66, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00},
|
{0xc0, 0x60, 0x60, 0x30, 0x18, 0x3c, 0x66, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00},
|
||||||
{0x00, 0x00, 0xff, 0x60, 0x30, 0x18, 0x0c, 0x06, 0xff, 0x00, 0x00, 0x00, 0x00},
|
{0x00, 0x00, 0xff, 0x60, 0x30, 0x18, 0x0c, 0x06, 0xff, 0x00, 0x00, 0x00, 0x00},
|
||||||
{0x00, 0x00, 0x0f, 0x18, 0x18, 0x18, 0x38, 0xf0, 0x38, 0x18, 0x18, 0x18, 0x0f},
|
{0x00, 0x00, 0x0f, 0x18, 0x18, 0x18, 0x38, 0xf0, 0x38, 0x18, 0x18, 0x18, 0x0f},
|
||||||
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
|
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
|
||||||
{0x00, 0x00, 0xf0, 0x18, 0x18, 0x18, 0x1c, 0x0f, 0x1c, 0x18, 0x18, 0x18, 0xf0},
|
{0x00, 0x00, 0xf0, 0x18, 0x18, 0x18, 0x1c, 0x0f, 0x1c, 0x18, 0x18, 0x18, 0xf0},
|
||||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x8f, 0xf1, 0x60, 0x00, 0x00, 0x00}
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x8f, 0xf1, 0x60, 0x00, 0x00, 0x00}
|
||||||
};
|
};
|
||||||
|
|
||||||
RasterFont::RasterFont()
|
RasterFont::RasterFont()
|
||||||
{
|
{
|
||||||
// set GL modes
|
// set GL modes
|
||||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
// create the raster font
|
// create the raster font
|
||||||
fontOffset = glGenLists(128);
|
fontOffset = glGenLists(128);
|
||||||
for (int i = 32; i < 127; i++) {
|
for (int i = 32; i < 127; i++) {
|
||||||
glNewList(i + fontOffset, GL_COMPILE);
|
glNewList(i + fontOffset, GL_COMPILE);
|
||||||
glBitmap(8, 13, 0.0f, 2.0f, 10.0f, 0.0f, rasters[i - 32]);
|
glBitmap(8, 13, 0.0f, 2.0f, 10.0f, 0.0f, rasters[i - 32]);
|
||||||
glEndList();
|
glEndList();
|
||||||
}
|
}
|
||||||
|
|
||||||
temp_buffer = new char[TEMP_BUFFER_SIZE];
|
temp_buffer = new char[TEMP_BUFFER_SIZE];
|
||||||
}
|
}
|
||||||
|
|
||||||
RasterFont::~RasterFont()
|
RasterFont::~RasterFont()
|
||||||
{
|
{
|
||||||
glDeleteLists(fontOffset, 128);
|
glDeleteLists(fontOffset, 128);
|
||||||
delete [] temp_buffer;
|
delete [] temp_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterFont::printString(const char *s, double x, double y, double z)
|
void RasterFont::printString(const char *s, double x, double y, double z)
|
||||||
{
|
{
|
||||||
int length = (int)strlen(s);
|
int length = (int)strlen(s);
|
||||||
if (!length)
|
if (!length)
|
||||||
return;
|
return;
|
||||||
if (length >= TEMP_BUFFER_SIZE)
|
if (length >= TEMP_BUFFER_SIZE)
|
||||||
length = TEMP_BUFFER_SIZE - 1;
|
length = TEMP_BUFFER_SIZE - 1;
|
||||||
|
|
||||||
// Sanitize string to avoid GL errors.
|
// Sanitize string to avoid GL errors.
|
||||||
char *s2 = temp_buffer;
|
char *s2 = temp_buffer;
|
||||||
memcpy(s2, s, length);
|
memcpy(s2, s, length);
|
||||||
s2[length] = 0;
|
s2[length] = 0;
|
||||||
for (int i = 0; i < length; i++)
|
for (int i = 0; i < length; i++)
|
||||||
if (s2[i] < 32 || s2[i] > 126)
|
if (s2[i] < 32 || s2[i] > 126)
|
||||||
s2[i] = '!';
|
s2[i] = '!';
|
||||||
|
|
||||||
// go to the right spot
|
// go to the right spot
|
||||||
glRasterPos3d(x, y, z);
|
glRasterPos3d(x, y, z);
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
glPushAttrib (GL_LIST_BIT);
|
glPushAttrib (GL_LIST_BIT);
|
||||||
glListBase(fontOffset);
|
glListBase(fontOffset);
|
||||||
glCallLists((GLsizei)strlen(s2), GL_UNSIGNED_BYTE, (GLubyte *) s2);
|
glCallLists((GLsizei)strlen(s2), GL_UNSIGNED_BYTE, (GLubyte *) s2);
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
glPopAttrib();
|
glPopAttrib();
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterFont::printCenteredString(const char *s, double y, int screen_width, double z)
|
void RasterFont::printCenteredString(const char *s, double y, int screen_width, double z)
|
||||||
{
|
{
|
||||||
int length = (int)strlen(s);
|
int length = (int)strlen(s);
|
||||||
int x = (int)(screen_width/2.0 - (length/2.0)*char_width);
|
int x = (int)(screen_width/2.0 - (length/2.0)*char_width);
|
||||||
printString(s, x, y, z);
|
printString(s, x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterFont::printMultilineText(const char *text, double start_x, double start_y, double z, int bbWidth, int bbHeight)
|
void RasterFont::printMultilineText(const char *text, double start_x, double start_y, double z, int bbWidth, int bbHeight)
|
||||||
{
|
{
|
||||||
double x = start_x;
|
double x = start_x;
|
||||||
double y = start_y;
|
double y = start_y;
|
||||||
char temp[1024];
|
char temp[1024];
|
||||||
char *t = temp;
|
char *t = temp;
|
||||||
while (*text)
|
while (*text)
|
||||||
{
|
{
|
||||||
if (*text == '\n')
|
if (*text == '\n')
|
||||||
{
|
{
|
||||||
*t = 0;
|
*t = 0;
|
||||||
printString(temp, x, y, z);
|
printString(temp, x, y, z);
|
||||||
y -= char_height * 2.0f / bbHeight;
|
y -= char_height * 2.0f / bbHeight;
|
||||||
x = start_x;
|
x = start_x;
|
||||||
t = temp;
|
t = temp;
|
||||||
}
|
}
|
||||||
else if (*text == '\r')
|
else if (*text == '\r')
|
||||||
{
|
{
|
||||||
t = temp;
|
t = temp;
|
||||||
}
|
}
|
||||||
else if (*text == '\t')
|
else if (*text == '\t')
|
||||||
{
|
{
|
||||||
//todo: add tabs every something like 4*char_width
|
//todo: add tabs every something like 4*char_width
|
||||||
*t = 0;
|
*t = 0;
|
||||||
int cpos = (int)strlen(temp);
|
int cpos = (int)strlen(temp);
|
||||||
int newpos = (cpos + 4) & (~3);
|
int newpos = (cpos + 4) & (~3);
|
||||||
printString(temp, x, y, z);
|
printString(temp, x, y, z);
|
||||||
x = start_x + (char_width*newpos) * 2.0f / bbWidth;
|
x = start_x + (char_width*newpos) * 2.0f / bbWidth;
|
||||||
t = temp;
|
t = temp;
|
||||||
*t++ = ' ';
|
*t++ = ' ';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
*t++ = *text;
|
*t++ = *text;
|
||||||
|
|
||||||
text++;
|
text++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ????
|
// ????
|
||||||
if (t != text)
|
if (t != text)
|
||||||
{
|
{
|
||||||
*t = 0;
|
*t = 0;
|
||||||
printString(temp, x, y, z);
|
printString(temp, x, y, z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,51 +1,51 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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/
|
||||||
|
|
||||||
#ifndef _OGL_RASTERFONT_H_
|
#ifndef _OGL_RASTERFONT_H_
|
||||||
#define _OGL_RASTERFONT_H_
|
#define _OGL_RASTERFONT_H_
|
||||||
|
|
||||||
namespace OGL
|
namespace OGL
|
||||||
{
|
{
|
||||||
|
|
||||||
class RasterFont {
|
class RasterFont {
|
||||||
public:
|
public:
|
||||||
RasterFont();
|
RasterFont();
|
||||||
~RasterFont(void);
|
~RasterFont(void);
|
||||||
static int debug;
|
static int debug;
|
||||||
|
|
||||||
// some useful constants
|
// some useful constants
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
char_width = 10,
|
char_width = 10,
|
||||||
char_height = 15,
|
char_height = 15,
|
||||||
};
|
};
|
||||||
|
|
||||||
// and the happy helper functions
|
// and the happy helper functions
|
||||||
void printString(const char *s, double x, double y, double z=0.0);
|
void printString(const char *s, double x, double y, double z=0.0);
|
||||||
void printCenteredString(const char *s, double y, int screen_width, double z=0.0);
|
void printCenteredString(const char *s, double y, int screen_width, double z=0.0);
|
||||||
|
|
||||||
void printMultilineText(const char *text, double x, double y, double z, int bbWidth, int bbHeight);
|
void printMultilineText(const char *text, double x, double y, double z, int bbWidth, int bbHeight);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int fontOffset;
|
int fontOffset;
|
||||||
char *temp_buffer;
|
char *temp_buffer;
|
||||||
enum {TEMP_BUFFER_SIZE = 64 * 1024};
|
enum {TEMP_BUFFER_SIZE = 64 * 1024};
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // _RASTERFONT_H_
|
#endif // _RASTERFONT_H_
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,61 +1,61 @@
|
|||||||
|
|
||||||
#ifndef _OGL_RENDER_H_
|
#ifndef _OGL_RENDER_H_
|
||||||
#define _OGL_RENDER_H_
|
#define _OGL_RENDER_H_
|
||||||
|
|
||||||
#include "MathUtil.h"
|
#include "MathUtil.h"
|
||||||
|
|
||||||
#include "VideoCommon.h"
|
#include "VideoCommon.h"
|
||||||
#include "Renderer.h"
|
#include "Renderer.h"
|
||||||
#include "pluginspecs_video.h"
|
#include "pluginspecs_video.h"
|
||||||
|
|
||||||
namespace OGL
|
namespace OGL
|
||||||
{
|
{
|
||||||
|
|
||||||
extern int OSDChoice;
|
extern int OSDChoice;
|
||||||
|
|
||||||
class Renderer : public ::RendererBase
|
class Renderer : public ::RendererBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Renderer();
|
Renderer();
|
||||||
~Renderer();
|
~Renderer();
|
||||||
|
|
||||||
// What's the real difference between these? Too similar names.
|
// What's the real difference between these? Too similar names.
|
||||||
void ResetAPIState();
|
void ResetAPIState();
|
||||||
void RestoreAPIState();
|
void RestoreAPIState();
|
||||||
|
|
||||||
void SetColorMask();
|
void SetColorMask();
|
||||||
void SetBlendMode(bool forceUpdate);
|
void SetBlendMode(bool forceUpdate);
|
||||||
bool SetScissorRect();
|
bool SetScissorRect();
|
||||||
void SetGenerationMode();
|
void SetGenerationMode();
|
||||||
void SetDepthMode();
|
void SetDepthMode();
|
||||||
void SetLogicOpMode();
|
void SetLogicOpMode();
|
||||||
void SetDitherMode();
|
void SetDitherMode();
|
||||||
void SetLineWidth();
|
void SetLineWidth();
|
||||||
|
|
||||||
// Live resolution change
|
// Live resolution change
|
||||||
bool Allow2x();
|
bool Allow2x();
|
||||||
bool AllowCustom();
|
bool AllowCustom();
|
||||||
|
|
||||||
u32 AccessEFB(EFBAccessType type, int x, int y);
|
u32 AccessEFB(EFBAccessType type, int x, int y);
|
||||||
|
|
||||||
void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z);
|
void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z);
|
||||||
void UpdateViewport();
|
void UpdateViewport();
|
||||||
|
|
||||||
// virtual funcs used by RendererBase::Swap
|
// virtual funcs used by RendererBase::Swap
|
||||||
void PrepareXFBCopy(const TargetRectangle &dst_rect);
|
void PrepareXFBCopy(const TargetRectangle &dst_rect);
|
||||||
void Draw(const XFBSourceBase* xfbSource, const TargetRectangle& sourceRc,
|
void Draw(const XFBSourceBase* xfbSource, const TargetRectangle& sourceRc,
|
||||||
const MathUtil::Rectangle<float>& drawRc, const EFBRectangle& rc);
|
const MathUtil::Rectangle<float>& drawRc, const EFBRectangle& rc);
|
||||||
void EndFrame();
|
void EndFrame();
|
||||||
void Present();
|
void Present();
|
||||||
bool CheckForResize();
|
bool CheckForResize();
|
||||||
void GetBackBufferSize(int* w, int* h);
|
void GetBackBufferSize(int* w, int* h);
|
||||||
void RecreateFramebufferManger();
|
void RecreateFramebufferManger();
|
||||||
void BeginFrame();
|
void BeginFrame();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,339 +1,339 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define _interlockedbittestandset workaround_ms_header_bug_platform_sdk6_set
|
#define _interlockedbittestandset workaround_ms_header_bug_platform_sdk6_set
|
||||||
#define _interlockedbittestandreset workaround_ms_header_bug_platform_sdk6_reset
|
#define _interlockedbittestandreset workaround_ms_header_bug_platform_sdk6_reset
|
||||||
#define _interlockedbittestandset64 workaround_ms_header_bug_platform_sdk6_set64
|
#define _interlockedbittestandset64 workaround_ms_header_bug_platform_sdk6_set64
|
||||||
#define _interlockedbittestandreset64 workaround_ms_header_bug_platform_sdk6_reset64
|
#define _interlockedbittestandreset64 workaround_ms_header_bug_platform_sdk6_reset64
|
||||||
#include <intrin.h>
|
#include <intrin.h>
|
||||||
#undef _interlockedbittestandset
|
#undef _interlockedbittestandset
|
||||||
#undef _interlockedbittestandreset
|
#undef _interlockedbittestandreset
|
||||||
#undef _interlockedbittestandset64
|
#undef _interlockedbittestandset64
|
||||||
#undef _interlockedbittestandreset64
|
#undef _interlockedbittestandreset64
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Common
|
// Common
|
||||||
#include "CommonPaths.h"
|
#include "CommonPaths.h"
|
||||||
#include "StringUtil.h"
|
#include "StringUtil.h"
|
||||||
#include "MemoryUtil.h"
|
#include "MemoryUtil.h"
|
||||||
#include "FileUtil.h"
|
#include "FileUtil.h"
|
||||||
|
|
||||||
// VideoCommon
|
// VideoCommon
|
||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
#include "Hash.h"
|
#include "Hash.h"
|
||||||
#include "Statistics.h"
|
#include "Statistics.h"
|
||||||
#include "Profiler.h"
|
#include "Profiler.h"
|
||||||
#include "ImageWrite.h"
|
#include "ImageWrite.h"
|
||||||
#include "BPStructs.h"
|
#include "BPStructs.h"
|
||||||
#include "TextureDecoder.h"
|
#include "TextureDecoder.h"
|
||||||
#include "PixelShaderManager.h"
|
#include "PixelShaderManager.h"
|
||||||
#include "HiresTextures.h"
|
#include "HiresTextures.h"
|
||||||
#include "VertexShaderManager.h"
|
#include "VertexShaderManager.h"
|
||||||
|
|
||||||
// OGL
|
// OGL
|
||||||
#include "OGL_TextureCache.h"
|
#include "OGL_TextureCache.h"
|
||||||
#include "OGL_PixelShaderCache.h"
|
#include "OGL_PixelShaderCache.h"
|
||||||
#include "OGL_TextureConverter.h"
|
#include "OGL_TextureConverter.h"
|
||||||
#include "OGL_FramebufferManager.h"
|
#include "OGL_FramebufferManager.h"
|
||||||
|
|
||||||
#include "../Main.h"
|
#include "../Main.h"
|
||||||
|
|
||||||
namespace OGL
|
namespace OGL
|
||||||
{
|
{
|
||||||
|
|
||||||
static u32 s_TempFramebuffer = 0;
|
static u32 s_TempFramebuffer = 0;
|
||||||
|
|
||||||
static const GLint c_MinLinearFilter[8] = {
|
static const GLint c_MinLinearFilter[8] = {
|
||||||
GL_NEAREST,
|
GL_NEAREST,
|
||||||
GL_NEAREST_MIPMAP_NEAREST,
|
GL_NEAREST_MIPMAP_NEAREST,
|
||||||
GL_NEAREST_MIPMAP_LINEAR,
|
GL_NEAREST_MIPMAP_LINEAR,
|
||||||
GL_NEAREST,
|
GL_NEAREST,
|
||||||
GL_LINEAR,
|
GL_LINEAR,
|
||||||
GL_LINEAR_MIPMAP_NEAREST,
|
GL_LINEAR_MIPMAP_NEAREST,
|
||||||
GL_LINEAR_MIPMAP_LINEAR,
|
GL_LINEAR_MIPMAP_LINEAR,
|
||||||
GL_LINEAR,
|
GL_LINEAR,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const GLint c_WrapSettings[4] = {
|
static const GLint c_WrapSettings[4] = {
|
||||||
GL_CLAMP_TO_EDGE,
|
GL_CLAMP_TO_EDGE,
|
||||||
GL_REPEAT,
|
GL_REPEAT,
|
||||||
GL_MIRRORED_REPEAT,
|
GL_MIRRORED_REPEAT,
|
||||||
GL_REPEAT,
|
GL_REPEAT,
|
||||||
};
|
};
|
||||||
|
|
||||||
TextureCache::TCacheEntry::~TCacheEntry()
|
TextureCache::TCacheEntry::~TCacheEntry()
|
||||||
{
|
{
|
||||||
if (texture)
|
if (texture)
|
||||||
{
|
{
|
||||||
glDeleteTextures(1, &texture);
|
glDeleteTextures(1, &texture);
|
||||||
texture = 0;
|
texture = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureCache::TCacheEntry::TCacheEntry()
|
TextureCache::TCacheEntry::TCacheEntry()
|
||||||
{
|
{
|
||||||
glGenTextures(1, &texture);
|
glGenTextures(1, &texture);
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCache::TCacheEntry::Load(unsigned int width, unsigned int height,
|
void TextureCache::TCacheEntry::Load(unsigned int width, unsigned int height,
|
||||||
unsigned int expanded_width, unsigned int level)
|
unsigned int expanded_width, unsigned int level)
|
||||||
{
|
{
|
||||||
if (bHaveMipMaps)
|
if (bHaveMipMaps)
|
||||||
{
|
{
|
||||||
if (pcfmt != PC_TEX_FMT_DXT1)
|
if (pcfmt != PC_TEX_FMT_DXT1)
|
||||||
{
|
{
|
||||||
if (expanded_width != (int)width)
|
if (expanded_width != (int)width)
|
||||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, expanded_width);
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, expanded_width);
|
||||||
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, level, gl_iformat, width, height, 0, gl_format, gl_type, TextureCache::temp);
|
glTexImage2D(GL_TEXTURE_2D, level, gl_iformat, width, height, 0, gl_format, gl_type, TextureCache::temp);
|
||||||
|
|
||||||
if (expanded_width != (int)width)
|
if (expanded_width != (int)width)
|
||||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// TODO:
|
// TODO:
|
||||||
//glCompressedTexImage2D(target, level, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, width, height, 0, expanded_width*expanded_height/2, temp);
|
//glCompressedTexImage2D(target, level, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, width, height, 0, expanded_width*expanded_height/2, temp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
|
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, gl_iformat, width, height, 0, gl_format, gl_type, TextureCache::temp);
|
glTexImage2D(GL_TEXTURE_2D, 0, gl_iformat, width, height, 0, gl_format, gl_type, TextureCache::temp);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE);
|
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleByHalf,
|
void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleByHalf,
|
||||||
unsigned int cbufid, const float colmat[], const EFBRectangle &source_rect)
|
unsigned int cbufid, const float colmat[], const EFBRectangle &source_rect)
|
||||||
{
|
{
|
||||||
glBindTexture(GL_TEXTURE_2D, texture);
|
glBindTexture(GL_TEXTURE_2D, texture);
|
||||||
|
|
||||||
// Make sure to resolve anything we need to read from.
|
// Make sure to resolve anything we need to read from.
|
||||||
const GLuint read_texture = bFromZBuffer ? FramebufferManager::ResolveAndGetDepthTarget(source_rect) : FramebufferManager::ResolveAndGetRenderTarget(source_rect);
|
const GLuint read_texture = bFromZBuffer ? FramebufferManager::ResolveAndGetDepthTarget(source_rect) : FramebufferManager::ResolveAndGetRenderTarget(source_rect);
|
||||||
|
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
if (s_TempFramebuffer == 0)
|
if (s_TempFramebuffer == 0)
|
||||||
glGenFramebuffersEXT(1, (GLuint*)&s_TempFramebuffer);
|
glGenFramebuffersEXT(1, (GLuint*)&s_TempFramebuffer);
|
||||||
|
|
||||||
FramebufferManager::SetFramebuffer(s_TempFramebuffer);
|
FramebufferManager::SetFramebuffer(s_TempFramebuffer);
|
||||||
// Bind texture to temporary framebuffer
|
// Bind texture to temporary framebuffer
|
||||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, texture, 0);
|
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, texture, 0);
|
||||||
GL_REPORT_FBO_ERROR();
|
GL_REPORT_FBO_ERROR();
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glEnable(GL_TEXTURE_RECTANGLE_ARB);
|
glEnable(GL_TEXTURE_RECTANGLE_ARB);
|
||||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, read_texture);
|
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, read_texture);
|
||||||
|
|
||||||
glViewport(0, 0, Scaledw, Scaledh);
|
glViewport(0, 0, Scaledw, Scaledh);
|
||||||
|
|
||||||
PixelShaderCache::SetCurrentShader(bFromZBuffer ? PixelShaderCache::GetDepthMatrixProgram() : PixelShaderCache::GetColorMatrixProgram());
|
PixelShaderCache::SetCurrentShader(bFromZBuffer ? PixelShaderCache::GetDepthMatrixProgram() : PixelShaderCache::GetColorMatrixProgram());
|
||||||
const float* const fConstAdd = colmat + 16; // fConstAdd is the last 4 floats of colmat
|
const float* const fConstAdd = colmat + 16; // fConstAdd is the last 4 floats of colmat
|
||||||
PixelShaderManager::SetColorMatrix(colmat, fConstAdd); // set transformation
|
PixelShaderManager::SetColorMatrix(colmat, fConstAdd); // set transformation
|
||||||
|
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(source_rect);
|
TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(source_rect);
|
||||||
|
|
||||||
glBegin(GL_QUADS);
|
glBegin(GL_QUADS);
|
||||||
glTexCoord2f((GLfloat)targetSource.left, (GLfloat)targetSource.bottom); glVertex2f(-1, 1);
|
glTexCoord2f((GLfloat)targetSource.left, (GLfloat)targetSource.bottom); glVertex2f(-1, 1);
|
||||||
glTexCoord2f((GLfloat)targetSource.left, (GLfloat)targetSource.top ); glVertex2f(-1, -1);
|
glTexCoord2f((GLfloat)targetSource.left, (GLfloat)targetSource.top ); glVertex2f(-1, -1);
|
||||||
glTexCoord2f((GLfloat)targetSource.right, (GLfloat)targetSource.top ); glVertex2f( 1, -1);
|
glTexCoord2f((GLfloat)targetSource.right, (GLfloat)targetSource.top ); glVertex2f( 1, -1);
|
||||||
glTexCoord2f((GLfloat)targetSource.right, (GLfloat)targetSource.bottom); glVertex2f( 1, 1);
|
glTexCoord2f((GLfloat)targetSource.right, (GLfloat)targetSource.bottom); glVertex2f( 1, 1);
|
||||||
glEnd();
|
glEnd();
|
||||||
|
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
// Unbind texture from temporary framebuffer
|
// Unbind texture from temporary framebuffer
|
||||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, 0, 0);
|
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, 0, 0);
|
||||||
|
|
||||||
// TODO: these good here?
|
// TODO: these good here?
|
||||||
FramebufferManager::SetFramebuffer(0);
|
FramebufferManager::SetFramebuffer(0);
|
||||||
VertexShaderManager::SetViewportChanged();
|
VertexShaderManager::SetViewportChanged();
|
||||||
DisableStage(0);
|
DisableStage(0);
|
||||||
|
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
// TODO: do this?
|
// TODO: do this?
|
||||||
//glBindTexture(GL_TEXTURE_2D, 0);
|
//glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCache::TCacheEntry::Bind(unsigned int stage)
|
void TextureCache::TCacheEntry::Bind(unsigned int stage)
|
||||||
{
|
{
|
||||||
glBindTexture(GL_TEXTURE_2D, texture);
|
glBindTexture(GL_TEXTURE_2D, texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureCache::TCacheEntryBase* TextureCache::CreateTexture(unsigned int width,
|
TextureCache::TCacheEntryBase* TextureCache::CreateTexture(unsigned int width,
|
||||||
unsigned int height, unsigned int expanded_width,
|
unsigned int height, unsigned int expanded_width,
|
||||||
unsigned int tex_levels, PC_TexFormat pcfmt)
|
unsigned int tex_levels, PC_TexFormat pcfmt)
|
||||||
{
|
{
|
||||||
TCacheEntry &entry = *new TCacheEntry;
|
TCacheEntry &entry = *new TCacheEntry;
|
||||||
|
|
||||||
int gl_format = 0;
|
int gl_format = 0;
|
||||||
int gl_iformat = 0;
|
int gl_iformat = 0;
|
||||||
int gl_type = 0;
|
int gl_type = 0;
|
||||||
|
|
||||||
if (pcfmt != PC_TEX_FMT_DXT1)
|
if (pcfmt != PC_TEX_FMT_DXT1)
|
||||||
{
|
{
|
||||||
switch (pcfmt)
|
switch (pcfmt)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
case PC_TEX_FMT_NONE:
|
case PC_TEX_FMT_NONE:
|
||||||
PanicAlert("Invalid PC texture format %i", pcfmt);
|
PanicAlert("Invalid PC texture format %i", pcfmt);
|
||||||
case PC_TEX_FMT_BGRA32:
|
case PC_TEX_FMT_BGRA32:
|
||||||
gl_format = GL_BGRA;
|
gl_format = GL_BGRA;
|
||||||
gl_iformat = 4;
|
gl_iformat = 4;
|
||||||
gl_type = GL_UNSIGNED_BYTE;
|
gl_type = GL_UNSIGNED_BYTE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PC_TEX_FMT_RGBA32:
|
case PC_TEX_FMT_RGBA32:
|
||||||
gl_format = GL_RGBA;
|
gl_format = GL_RGBA;
|
||||||
gl_iformat = 4;
|
gl_iformat = 4;
|
||||||
gl_type = GL_UNSIGNED_BYTE;
|
gl_type = GL_UNSIGNED_BYTE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PC_TEX_FMT_I4_AS_I8:
|
case PC_TEX_FMT_I4_AS_I8:
|
||||||
gl_format = GL_LUMINANCE;
|
gl_format = GL_LUMINANCE;
|
||||||
gl_iformat = GL_INTENSITY4;
|
gl_iformat = GL_INTENSITY4;
|
||||||
gl_type = GL_UNSIGNED_BYTE;
|
gl_type = GL_UNSIGNED_BYTE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PC_TEX_FMT_IA4_AS_IA8:
|
case PC_TEX_FMT_IA4_AS_IA8:
|
||||||
gl_format = GL_LUMINANCE_ALPHA;
|
gl_format = GL_LUMINANCE_ALPHA;
|
||||||
gl_iformat = GL_LUMINANCE4_ALPHA4;
|
gl_iformat = GL_LUMINANCE4_ALPHA4;
|
||||||
gl_type = GL_UNSIGNED_BYTE;
|
gl_type = GL_UNSIGNED_BYTE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PC_TEX_FMT_I8:
|
case PC_TEX_FMT_I8:
|
||||||
gl_format = GL_LUMINANCE;
|
gl_format = GL_LUMINANCE;
|
||||||
gl_iformat = GL_INTENSITY8;
|
gl_iformat = GL_INTENSITY8;
|
||||||
gl_type = GL_UNSIGNED_BYTE;
|
gl_type = GL_UNSIGNED_BYTE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PC_TEX_FMT_IA8:
|
case PC_TEX_FMT_IA8:
|
||||||
gl_format = GL_LUMINANCE_ALPHA;
|
gl_format = GL_LUMINANCE_ALPHA;
|
||||||
gl_iformat = GL_LUMINANCE8_ALPHA8;
|
gl_iformat = GL_LUMINANCE8_ALPHA8;
|
||||||
gl_type = GL_UNSIGNED_BYTE;
|
gl_type = GL_UNSIGNED_BYTE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PC_TEX_FMT_RGB565:
|
case PC_TEX_FMT_RGB565:
|
||||||
gl_format = GL_RGB;
|
gl_format = GL_RGB;
|
||||||
gl_iformat = GL_RGB;
|
gl_iformat = GL_RGB;
|
||||||
gl_type = GL_UNSIGNED_SHORT_5_6_5;
|
gl_type = GL_UNSIGNED_SHORT_5_6_5;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
entry.gl_format = gl_format;
|
entry.gl_format = gl_format;
|
||||||
entry.gl_iformat = gl_iformat;
|
entry.gl_iformat = gl_iformat;
|
||||||
entry.gl_type = gl_type;
|
entry.gl_type = gl_type;
|
||||||
|
|
||||||
// ok?
|
// ok?
|
||||||
//Load(width, height, expanded_width, level);
|
//Load(width, height, expanded_width, level);
|
||||||
|
|
||||||
return &entry;
|
return &entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureCache::TCacheEntryBase* TextureCache::CreateRenderTargetTexture(int scaled_tex_w, int scaled_tex_h)
|
TextureCache::TCacheEntryBase* TextureCache::CreateRenderTargetTexture(int scaled_tex_w, int scaled_tex_h)
|
||||||
{
|
{
|
||||||
TCacheEntry &entry = *new TCacheEntry;
|
TCacheEntry &entry = *new TCacheEntry;
|
||||||
|
|
||||||
entry.isDynamic = false;
|
entry.isDynamic = false;
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, entry.texture);
|
glBindTexture(GL_TEXTURE_2D, entry.texture);
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
const GLenum gl_format = GL_RGBA,
|
const GLenum gl_format = GL_RGBA,
|
||||||
gl_iformat = 4,
|
gl_iformat = 4,
|
||||||
gl_type = GL_UNSIGNED_BYTE;
|
gl_type = GL_UNSIGNED_BYTE;
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, gl_iformat, scaled_tex_w, scaled_tex_w, 0, gl_format, gl_type, NULL);
|
glTexImage2D(GL_TEXTURE_2D, 0, gl_iformat, scaled_tex_w, scaled_tex_w, 0, gl_format, gl_type, NULL);
|
||||||
|
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
|
||||||
if (GL_REPORT_ERROR() != GL_NO_ERROR)
|
if (GL_REPORT_ERROR() != GL_NO_ERROR)
|
||||||
{
|
{
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
}
|
}
|
||||||
|
|
||||||
return &entry;
|
return &entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCache::TCacheEntry::SetTextureParameters(TexMode0 &newmode, TexMode1 &newmode1)
|
void TextureCache::TCacheEntry::SetTextureParameters(TexMode0 &newmode, TexMode1 &newmode1)
|
||||||
{
|
{
|
||||||
mode = newmode;
|
mode = newmode;
|
||||||
//mode1 = newmode1;
|
//mode1 = newmode1;
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
|
||||||
(newmode.mag_filter || g_Config.bForceFiltering) ? GL_LINEAR : GL_NEAREST);
|
(newmode.mag_filter || g_Config.bForceFiltering) ? GL_LINEAR : GL_NEAREST);
|
||||||
|
|
||||||
if (bHaveMipMaps)
|
if (bHaveMipMaps)
|
||||||
{
|
{
|
||||||
if (g_ActiveConfig.bForceFiltering && newmode.min_filter < 4)
|
if (g_ActiveConfig.bForceFiltering && newmode.min_filter < 4)
|
||||||
mode.min_filter += 4; // take equivalent forced linear
|
mode.min_filter += 4; // take equivalent forced linear
|
||||||
|
|
||||||
int filt = newmode.min_filter;
|
int filt = newmode.min_filter;
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, c_MinLinearFilter[filt & 7]);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, c_MinLinearFilter[filt & 7]);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, newmode1.min_lod >> 4);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, newmode1.min_lod >> 4);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, newmode1.max_lod >> 4);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, newmode1.max_lod >> 4);
|
||||||
glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, (newmode.lod_bias/32.0f));
|
glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, (newmode.lod_bias/32.0f));
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
||||||
(g_ActiveConfig.bForceFiltering || newmode.min_filter >= 4) ? GL_LINEAR : GL_NEAREST);
|
(g_ActiveConfig.bForceFiltering || newmode.min_filter >= 4) ? GL_LINEAR : GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, c_WrapSettings[newmode.wrap_s]);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, c_WrapSettings[newmode.wrap_s]);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, c_WrapSettings[newmode.wrap_t]);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, c_WrapSettings[newmode.wrap_t]);
|
||||||
|
|
||||||
if (g_Config.iMaxAnisotropy >= 1)
|
if (g_Config.iMaxAnisotropy >= 1)
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)(1 << g_ActiveConfig.iMaxAnisotropy));
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)(1 << g_ActiveConfig.iMaxAnisotropy));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureCache::~TextureCache()
|
TextureCache::~TextureCache()
|
||||||
{
|
{
|
||||||
if (s_TempFramebuffer)
|
if (s_TempFramebuffer)
|
||||||
{
|
{
|
||||||
glDeleteFramebuffersEXT(1, (GLuint *)&s_TempFramebuffer);
|
glDeleteFramebuffersEXT(1, (GLuint *)&s_TempFramebuffer);
|
||||||
s_TempFramebuffer = 0;
|
s_TempFramebuffer = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCache::DisableStage(int stage)
|
void TextureCache::DisableStage(int stage)
|
||||||
{
|
{
|
||||||
glActiveTexture(GL_TEXTURE0 + stage);
|
glActiveTexture(GL_TEXTURE0 + stage);
|
||||||
glDisable(GL_TEXTURE_2D);
|
glDisable(GL_TEXTURE_2D);
|
||||||
glDisable(GL_TEXTURE_RECTANGLE_ARB);
|
glDisable(GL_TEXTURE_RECTANGLE_ARB);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,80 +1,80 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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/
|
||||||
|
|
||||||
#ifndef _OGL_TEXTURECACHE_H_
|
#ifndef _OGL_TEXTURECACHE_H_
|
||||||
#define _OGL_TEXTURECACHE_H_
|
#define _OGL_TEXTURECACHE_H_
|
||||||
|
|
||||||
#include "VideoCommon.h"
|
#include "VideoCommon.h"
|
||||||
#include "BPMemory.h"
|
#include "BPMemory.h"
|
||||||
|
|
||||||
#include "OGL_GLUtil.h"
|
#include "OGL_GLUtil.h"
|
||||||
|
|
||||||
#include "../TextureCache.h"
|
#include "../TextureCache.h"
|
||||||
|
|
||||||
namespace OGL
|
namespace OGL
|
||||||
{
|
{
|
||||||
|
|
||||||
class TextureCache : public ::TextureCacheBase
|
class TextureCache : public ::TextureCacheBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
struct TCacheEntry : TCacheEntryBase
|
struct TCacheEntry : TCacheEntryBase
|
||||||
{
|
{
|
||||||
GLuint texture;
|
GLuint texture;
|
||||||
|
|
||||||
bool isDynamic;
|
bool isDynamic;
|
||||||
bool bHaveMipMaps;
|
bool bHaveMipMaps;
|
||||||
|
|
||||||
PC_TexFormat pcfmt;
|
PC_TexFormat pcfmt;
|
||||||
|
|
||||||
int gl_format;
|
int gl_format;
|
||||||
int gl_iformat;
|
int gl_iformat;
|
||||||
int gl_type;
|
int gl_type;
|
||||||
|
|
||||||
TexMode0 mode; // current filter and clamp modes that texture is set to
|
TexMode0 mode; // current filter and clamp modes that texture is set to
|
||||||
TexMode1 mode1; // current filter and clamp modes that texture is set to
|
TexMode1 mode1; // current filter and clamp modes that texture is set to
|
||||||
|
|
||||||
void SetTextureParameters(TexMode0 &newmode, TexMode1 &newmode1);
|
void SetTextureParameters(TexMode0 &newmode, TexMode1 &newmode1);
|
||||||
|
|
||||||
TCacheEntry();
|
TCacheEntry();
|
||||||
~TCacheEntry();
|
~TCacheEntry();
|
||||||
|
|
||||||
void Load(unsigned int width, unsigned int height,
|
void Load(unsigned int width, unsigned int height,
|
||||||
unsigned int expanded_width, unsigned int level);
|
unsigned int expanded_width, unsigned int level);
|
||||||
|
|
||||||
void FromRenderTarget(bool bFromZBuffer, bool bScaleByHalf,
|
void FromRenderTarget(bool bFromZBuffer, bool bScaleByHalf,
|
||||||
unsigned int cbufid, const float colmat[], const EFBRectangle &source_rect);
|
unsigned int cbufid, const float colmat[], const EFBRectangle &source_rect);
|
||||||
|
|
||||||
void Bind(unsigned int stage);
|
void Bind(unsigned int stage);
|
||||||
};
|
};
|
||||||
|
|
||||||
~TextureCache();
|
~TextureCache();
|
||||||
|
|
||||||
TCacheEntryBase* CreateTexture(unsigned int width, unsigned int height,
|
TCacheEntryBase* CreateTexture(unsigned int width, unsigned int height,
|
||||||
unsigned int expanded_width, unsigned int tex_levels, PC_TexFormat pcfmt);
|
unsigned int expanded_width, unsigned int tex_levels, PC_TexFormat pcfmt);
|
||||||
|
|
||||||
TCacheEntryBase* CreateRenderTargetTexture(int scaled_tex_w, int scaled_tex_h);
|
TCacheEntryBase* CreateRenderTargetTexture(int scaled_tex_w, int scaled_tex_h);
|
||||||
|
|
||||||
void CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, unsigned int bScaleByHalf, const EFBRectangle &source);
|
void CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, unsigned int bScaleByHalf, const EFBRectangle &source);
|
||||||
|
|
||||||
static void DisableStage(int stage); // sets active texture
|
static void DisableStage(int stage); // sets active texture
|
||||||
};
|
};
|
||||||
|
|
||||||
//bool SaveTexture(const char* filename, u32 textarget, u32 tex, int width, int height);
|
//bool SaveTexture(const char* filename, u32 textarget, u32 tex, int width, int height);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // _TEXTUREMNGR_H_
|
#endif // _TEXTUREMNGR_H_
|
||||||
|
|||||||
@@ -1,486 +1,486 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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/
|
||||||
|
|
||||||
// Fast image conversion using OpenGL shaders.
|
// Fast image conversion using OpenGL shaders.
|
||||||
// This kind of stuff would be a LOT nicer with OpenCL.
|
// This kind of stuff would be a LOT nicer with OpenCL.
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
// Common
|
// Common
|
||||||
#include "FileUtil.h"
|
#include "FileUtil.h"
|
||||||
|
|
||||||
// VideoCommon
|
// VideoCommon
|
||||||
#include "TextureConversionShader.h"
|
#include "TextureConversionShader.h"
|
||||||
#include "VertexShaderManager.h"
|
#include "VertexShaderManager.h"
|
||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
#include "ImageWrite.h"
|
#include "ImageWrite.h"
|
||||||
|
|
||||||
// OGL
|
// OGL
|
||||||
#include "OGL_Render.h"
|
#include "OGL_Render.h"
|
||||||
#include "OGL_TextureConverter.h"
|
#include "OGL_TextureConverter.h"
|
||||||
#include "OGL_TextureCache.h"
|
#include "OGL_TextureCache.h"
|
||||||
#include "OGL_PixelShaderCache.h"
|
#include "OGL_PixelShaderCache.h"
|
||||||
#include "OGL_FramebufferManager.h"
|
#include "OGL_FramebufferManager.h"
|
||||||
|
|
||||||
#include "../Main.h"
|
#include "../Main.h"
|
||||||
|
|
||||||
namespace OGL
|
namespace OGL
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace TextureConverter
|
namespace TextureConverter
|
||||||
{
|
{
|
||||||
|
|
||||||
static GLuint s_texConvFrameBuffer = 0;
|
static GLuint s_texConvFrameBuffer = 0;
|
||||||
static GLuint s_srcTexture = 0; // for decoding from RAM
|
static GLuint s_srcTexture = 0; // for decoding from RAM
|
||||||
static GLuint s_srcTextureWidth = 0;
|
static GLuint s_srcTextureWidth = 0;
|
||||||
static GLuint s_srcTextureHeight = 0;
|
static GLuint s_srcTextureHeight = 0;
|
||||||
static GLuint s_dstRenderBuffer = 0; // for encoding to RAM
|
static GLuint s_dstRenderBuffer = 0; // for encoding to RAM
|
||||||
|
|
||||||
const int renderBufferWidth = 1024;
|
const int renderBufferWidth = 1024;
|
||||||
const int renderBufferHeight = 1024;
|
const int renderBufferHeight = 1024;
|
||||||
|
|
||||||
static FRAGMENTSHADER s_rgbToYuyvProgram;
|
static FRAGMENTSHADER s_rgbToYuyvProgram;
|
||||||
static FRAGMENTSHADER s_yuyvToRgbProgram;
|
static FRAGMENTSHADER s_yuyvToRgbProgram;
|
||||||
|
|
||||||
// Not all slots are taken - but who cares.
|
// Not all slots are taken - but who cares.
|
||||||
const u32 NUM_ENCODING_PROGRAMS = 64;
|
const u32 NUM_ENCODING_PROGRAMS = 64;
|
||||||
static FRAGMENTSHADER s_encodingPrograms[NUM_ENCODING_PROGRAMS];
|
static FRAGMENTSHADER s_encodingPrograms[NUM_ENCODING_PROGRAMS];
|
||||||
|
|
||||||
void CreateRgbToYuyvProgram()
|
void CreateRgbToYuyvProgram()
|
||||||
{
|
{
|
||||||
// Output is BGRA because that is slightly faster than RGBA.
|
// Output is BGRA because that is slightly faster than RGBA.
|
||||||
const char *FProgram =
|
const char *FProgram =
|
||||||
"uniform samplerRECT samp0 : register(s0);\n"
|
"uniform samplerRECT samp0 : register(s0);\n"
|
||||||
"void main(\n"
|
"void main(\n"
|
||||||
" out float4 ocol0 : COLOR0,\n"
|
" out float4 ocol0 : COLOR0,\n"
|
||||||
" in float2 uv0 : TEXCOORD0)\n"
|
" in float2 uv0 : TEXCOORD0)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" float2 uv1 = float2(uv0.x + 1.0f, uv0.y);\n"
|
" float2 uv1 = float2(uv0.x + 1.0f, uv0.y);\n"
|
||||||
" float3 c0 = texRECT(samp0, uv0).rgb;\n"
|
" float3 c0 = texRECT(samp0, uv0).rgb;\n"
|
||||||
" float3 c1 = texRECT(samp0, uv1).rgb;\n"
|
" float3 c1 = texRECT(samp0, uv1).rgb;\n"
|
||||||
" float3 y_const = float3(0.257f,0.504f,0.098f);\n"
|
" float3 y_const = float3(0.257f,0.504f,0.098f);\n"
|
||||||
" float3 u_const = float3(-0.148f,-0.291f,0.439f);\n"
|
" float3 u_const = float3(-0.148f,-0.291f,0.439f);\n"
|
||||||
" float3 v_const = float3(0.439f,-0.368f,-0.071f);\n"
|
" float3 v_const = float3(0.439f,-0.368f,-0.071f);\n"
|
||||||
" float4 const3 = float4(0.0625f,0.5f,0.0625f,0.5f);\n"
|
" float4 const3 = float4(0.0625f,0.5f,0.0625f,0.5f);\n"
|
||||||
" float3 c01 = (c0 + c1) * 0.5f;\n"
|
" float3 c01 = (c0 + c1) * 0.5f;\n"
|
||||||
" ocol0 = float4(dot(c1,y_const),dot(c01,u_const),dot(c0,y_const),dot(c01, v_const)) + const3;\n"
|
" ocol0 = float4(dot(c1,y_const),dot(c01,u_const),dot(c0,y_const),dot(c01, v_const)) + const3;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
if (!PixelShaderCache::CompilePixelShader(s_rgbToYuyvProgram, FProgram)) {
|
if (!PixelShaderCache::CompilePixelShader(s_rgbToYuyvProgram, FProgram)) {
|
||||||
ERROR_LOG(VIDEO, "Failed to create RGB to YUYV fragment program");
|
ERROR_LOG(VIDEO, "Failed to create RGB to YUYV fragment program");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreateYuyvToRgbProgram()
|
void CreateYuyvToRgbProgram()
|
||||||
{
|
{
|
||||||
const char *FProgram =
|
const char *FProgram =
|
||||||
"uniform samplerRECT samp0 : register(s0);\n"
|
"uniform samplerRECT samp0 : register(s0);\n"
|
||||||
"void main(\n"
|
"void main(\n"
|
||||||
" out float4 ocol0 : COLOR0,\n"
|
" out float4 ocol0 : COLOR0,\n"
|
||||||
" in float2 uv0 : TEXCOORD0)\n"
|
" in float2 uv0 : TEXCOORD0)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" float4 c0 = texRECT(samp0, uv0).rgba;\n"
|
" float4 c0 = texRECT(samp0, uv0).rgba;\n"
|
||||||
|
|
||||||
" float f = step(0.5, frac(uv0.x));\n"
|
" float f = step(0.5, frac(uv0.x));\n"
|
||||||
" float y = lerp(c0.b, c0.r, f);\n"
|
" float y = lerp(c0.b, c0.r, f);\n"
|
||||||
" float yComp = 1.164f * (y - 0.0625f);\n"
|
" float yComp = 1.164f * (y - 0.0625f);\n"
|
||||||
" float uComp = c0.g - 0.5f;\n"
|
" float uComp = c0.g - 0.5f;\n"
|
||||||
" float vComp = c0.a - 0.5f;\n"
|
" float vComp = c0.a - 0.5f;\n"
|
||||||
|
|
||||||
" ocol0 = float4(yComp + (1.596f * vComp),\n"
|
" ocol0 = float4(yComp + (1.596f * vComp),\n"
|
||||||
" yComp - (0.813f * vComp) - (0.391f * uComp),\n"
|
" yComp - (0.813f * vComp) - (0.391f * uComp),\n"
|
||||||
" yComp + (2.018f * uComp),\n"
|
" yComp + (2.018f * uComp),\n"
|
||||||
" 1.0f);\n"
|
" 1.0f);\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
if (!PixelShaderCache::CompilePixelShader(s_yuyvToRgbProgram, FProgram)) {
|
if (!PixelShaderCache::CompilePixelShader(s_yuyvToRgbProgram, FProgram)) {
|
||||||
ERROR_LOG(VIDEO, "Failed to create YUYV to RGB fragment program");
|
ERROR_LOG(VIDEO, "Failed to create YUYV to RGB fragment program");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FRAGMENTSHADER &GetOrCreateEncodingShader(u32 format)
|
FRAGMENTSHADER &GetOrCreateEncodingShader(u32 format)
|
||||||
{
|
{
|
||||||
if (format > NUM_ENCODING_PROGRAMS)
|
if (format > NUM_ENCODING_PROGRAMS)
|
||||||
{
|
{
|
||||||
PanicAlert("Unknown texture copy format: 0x%x\n", format);
|
PanicAlert("Unknown texture copy format: 0x%x\n", format);
|
||||||
return s_encodingPrograms[0];
|
return s_encodingPrograms[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s_encodingPrograms[format].glprogid == 0)
|
if (s_encodingPrograms[format].glprogid == 0)
|
||||||
{
|
{
|
||||||
const char* shader = TextureConversionShader::GenerateEncodingShader(format,API_OPENGL);
|
const char* shader = TextureConversionShader::GenerateEncodingShader(format,API_OPENGL);
|
||||||
|
|
||||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||||
if (g_ActiveConfig.iLog & CONF_SAVESHADERS && shader) {
|
if (g_ActiveConfig.iLog & CONF_SAVESHADERS && shader) {
|
||||||
static int counter = 0;
|
static int counter = 0;
|
||||||
char szTemp[MAX_PATH];
|
char szTemp[MAX_PATH];
|
||||||
sprintf(szTemp, "%senc_%04i.txt", File::GetUserPath(D_DUMP_IDX), counter++);
|
sprintf(szTemp, "%senc_%04i.txt", File::GetUserPath(D_DUMP_IDX), counter++);
|
||||||
|
|
||||||
SaveData(szTemp, shader);
|
SaveData(szTemp, shader);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!PixelShaderCache::CompilePixelShader(s_encodingPrograms[format], shader)) {
|
if (!PixelShaderCache::CompilePixelShader(s_encodingPrograms[format], shader)) {
|
||||||
ERROR_LOG(VIDEO, "Failed to create encoding fragment program");
|
ERROR_LOG(VIDEO, "Failed to create encoding fragment program");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return s_encodingPrograms[format];
|
return s_encodingPrograms[format];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Init()
|
void Init()
|
||||||
{
|
{
|
||||||
glGenFramebuffersEXT(1, &s_texConvFrameBuffer);
|
glGenFramebuffersEXT(1, &s_texConvFrameBuffer);
|
||||||
|
|
||||||
glGenRenderbuffersEXT(1, &s_dstRenderBuffer);
|
glGenRenderbuffersEXT(1, &s_dstRenderBuffer);
|
||||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, s_dstRenderBuffer);
|
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, s_dstRenderBuffer);
|
||||||
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA, renderBufferWidth, renderBufferHeight);
|
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA, renderBufferWidth, renderBufferHeight);
|
||||||
|
|
||||||
glGenTextures(1, &s_srcTexture);
|
glGenTextures(1, &s_srcTexture);
|
||||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, s_srcTexture);
|
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, s_srcTexture);
|
||||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
|
||||||
CreateRgbToYuyvProgram();
|
CreateRgbToYuyvProgram();
|
||||||
CreateYuyvToRgbProgram();
|
CreateYuyvToRgbProgram();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shutdown()
|
void Shutdown()
|
||||||
{
|
{
|
||||||
glDeleteTextures(1, &s_srcTexture);
|
glDeleteTextures(1, &s_srcTexture);
|
||||||
glDeleteRenderbuffersEXT(1, &s_dstRenderBuffer);
|
glDeleteRenderbuffersEXT(1, &s_dstRenderBuffer);
|
||||||
glDeleteFramebuffersEXT(1, &s_texConvFrameBuffer);
|
glDeleteFramebuffersEXT(1, &s_texConvFrameBuffer);
|
||||||
|
|
||||||
s_rgbToYuyvProgram.Destroy();
|
s_rgbToYuyvProgram.Destroy();
|
||||||
s_yuyvToRgbProgram.Destroy();
|
s_yuyvToRgbProgram.Destroy();
|
||||||
|
|
||||||
for (unsigned int i = 0; i < NUM_ENCODING_PROGRAMS; i++)
|
for (unsigned int i = 0; i < NUM_ENCODING_PROGRAMS; i++)
|
||||||
s_encodingPrograms[i].Destroy();
|
s_encodingPrograms[i].Destroy();
|
||||||
|
|
||||||
s_srcTexture = 0;
|
s_srcTexture = 0;
|
||||||
s_dstRenderBuffer = 0;
|
s_dstRenderBuffer = 0;
|
||||||
s_texConvFrameBuffer = 0;
|
s_texConvFrameBuffer = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EncodeToRamUsingShader(FRAGMENTSHADER& shader, GLuint srcTexture, const TargetRectangle& sourceRc,
|
void EncodeToRamUsingShader(FRAGMENTSHADER& shader, GLuint srcTexture, const TargetRectangle& sourceRc,
|
||||||
u8* destAddr, int dstWidth, int dstHeight, int readStride, bool toTexture, bool linearFilter)
|
u8* destAddr, int dstWidth, int dstHeight, int readStride, bool toTexture, bool linearFilter)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
// switch to texture converter frame buffer
|
// switch to texture converter frame buffer
|
||||||
// attach render buffer as color destination
|
// attach render buffer as color destination
|
||||||
FramebufferManager::SetFramebuffer(s_texConvFrameBuffer);
|
FramebufferManager::SetFramebuffer(s_texConvFrameBuffer);
|
||||||
|
|
||||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, s_dstRenderBuffer);
|
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, s_dstRenderBuffer);
|
||||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, s_dstRenderBuffer);
|
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, s_dstRenderBuffer);
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
for (int i = 1; i < 8; ++i)
|
for (int i = 1; i < 8; ++i)
|
||||||
TextureCache::DisableStage(i);
|
TextureCache::DisableStage(i);
|
||||||
|
|
||||||
// set source texture
|
// set source texture
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glEnable(GL_TEXTURE_RECTANGLE_ARB);
|
glEnable(GL_TEXTURE_RECTANGLE_ARB);
|
||||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, srcTexture);
|
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, srcTexture);
|
||||||
|
|
||||||
if (linearFilter)
|
if (linearFilter)
|
||||||
{
|
{
|
||||||
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);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
}
|
}
|
||||||
|
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
glViewport(0, 0, (GLsizei)dstWidth, (GLsizei)dstHeight);
|
glViewport(0, 0, (GLsizei)dstWidth, (GLsizei)dstHeight);
|
||||||
|
|
||||||
PixelShaderCache::SetCurrentShader(shader.glprogid);
|
PixelShaderCache::SetCurrentShader(shader.glprogid);
|
||||||
|
|
||||||
// Draw...
|
// Draw...
|
||||||
glBegin(GL_QUADS);
|
glBegin(GL_QUADS);
|
||||||
glTexCoord2f((float)sourceRc.left, (float)sourceRc.top); glVertex2f(-1,-1);
|
glTexCoord2f((float)sourceRc.left, (float)sourceRc.top); glVertex2f(-1,-1);
|
||||||
glTexCoord2f((float)sourceRc.left, (float)sourceRc.bottom); glVertex2f(-1,1);
|
glTexCoord2f((float)sourceRc.left, (float)sourceRc.bottom); glVertex2f(-1,1);
|
||||||
glTexCoord2f((float)sourceRc.right, (float)sourceRc.bottom); glVertex2f(1,1);
|
glTexCoord2f((float)sourceRc.right, (float)sourceRc.bottom); glVertex2f(1,1);
|
||||||
glTexCoord2f((float)sourceRc.right, (float)sourceRc.top); glVertex2f(1,-1);
|
glTexCoord2f((float)sourceRc.right, (float)sourceRc.top); glVertex2f(1,-1);
|
||||||
glEnd();
|
glEnd();
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
// .. and then readback the results.
|
// .. and then readback the results.
|
||||||
// TODO: make this less slow.
|
// TODO: make this less slow.
|
||||||
|
|
||||||
int writeStride = bpmem.copyMipMapStrideChannels * 32;
|
int writeStride = bpmem.copyMipMapStrideChannels * 32;
|
||||||
|
|
||||||
if (writeStride != readStride && toTexture)
|
if (writeStride != readStride && toTexture)
|
||||||
{
|
{
|
||||||
// writing to a texture of a different size
|
// writing to a texture of a different size
|
||||||
|
|
||||||
int readHeight = readStride / dstWidth;
|
int readHeight = readStride / dstWidth;
|
||||||
readHeight /= 4; // 4 bytes per pixel
|
readHeight /= 4; // 4 bytes per pixel
|
||||||
|
|
||||||
int readStart = 0;
|
int readStart = 0;
|
||||||
int readLoops = dstHeight / readHeight;
|
int readLoops = dstHeight / readHeight;
|
||||||
for (int i = 0; i < readLoops; i++)
|
for (int i = 0; i < readLoops; i++)
|
||||||
{
|
{
|
||||||
glReadPixels(0, readStart, (GLsizei)dstWidth, (GLsizei)readHeight, GL_BGRA, GL_UNSIGNED_BYTE, destAddr);
|
glReadPixels(0, readStart, (GLsizei)dstWidth, (GLsizei)readHeight, GL_BGRA, GL_UNSIGNED_BYTE, destAddr);
|
||||||
|
|
||||||
readStart += readHeight;
|
readStart += readHeight;
|
||||||
destAddr += writeStride;
|
destAddr += writeStride;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
glReadPixels(0, 0, (GLsizei)dstWidth, (GLsizei)dstHeight, GL_BGRA, GL_UNSIGNED_BYTE, destAddr);
|
glReadPixels(0, 0, (GLsizei)dstWidth, (GLsizei)dstHeight, GL_BGRA, GL_UNSIGNED_BYTE, destAddr);
|
||||||
|
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source)
|
void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source)
|
||||||
{
|
{
|
||||||
u32 format = copyfmt;
|
u32 format = copyfmt;
|
||||||
|
|
||||||
if (bFromZBuffer)
|
if (bFromZBuffer)
|
||||||
{
|
{
|
||||||
format |= _GX_TF_ZTF;
|
format |= _GX_TF_ZTF;
|
||||||
if (copyfmt == 11)
|
if (copyfmt == 11)
|
||||||
format = GX_TF_Z16;
|
format = GX_TF_Z16;
|
||||||
else if (format < GX_TF_Z8 || format > GX_TF_Z24X8)
|
else if (format < GX_TF_Z8 || format > GX_TF_Z24X8)
|
||||||
format |= _GX_TF_CTF;
|
format |= _GX_TF_CTF;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if (copyfmt > GX_TF_RGBA8 || (copyfmt < GX_TF_RGB565 && !bIsIntensityFmt))
|
if (copyfmt > GX_TF_RGBA8 || (copyfmt < GX_TF_RGB565 && !bIsIntensityFmt))
|
||||||
format |= _GX_TF_CTF;
|
format |= _GX_TF_CTF;
|
||||||
|
|
||||||
FRAGMENTSHADER& texconv_shader = GetOrCreateEncodingShader(format);
|
FRAGMENTSHADER& texconv_shader = GetOrCreateEncodingShader(format);
|
||||||
if (texconv_shader.glprogid == 0)
|
if (texconv_shader.glprogid == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
u8 *dest_ptr = Memory_GetPtr(address);
|
u8 *dest_ptr = Memory_GetPtr(address);
|
||||||
|
|
||||||
GLuint source_texture = bFromZBuffer ? FramebufferManager::ResolveAndGetDepthTarget(source) : FramebufferManager::ResolveAndGetRenderTarget(source);
|
GLuint source_texture = bFromZBuffer ? FramebufferManager::ResolveAndGetDepthTarget(source) : FramebufferManager::ResolveAndGetRenderTarget(source);
|
||||||
|
|
||||||
int width = (source.right - source.left) >> bScaleByHalf;
|
int width = (source.right - source.left) >> bScaleByHalf;
|
||||||
int height = (source.bottom - source.top) >> bScaleByHalf;
|
int height = (source.bottom - source.top) >> bScaleByHalf;
|
||||||
|
|
||||||
int size_in_bytes = TexDecoder_GetTextureSizeInBytes(width, height, format);
|
int size_in_bytes = TexDecoder_GetTextureSizeInBytes(width, height, format);
|
||||||
|
|
||||||
// Invalidate any existing texture covering this memory range.
|
// Invalidate any existing texture covering this memory range.
|
||||||
// TODO - don't delete the texture if it already exists, just replace the contents.
|
// TODO - don't delete the texture if it already exists, just replace the contents.
|
||||||
TextureCache::InvalidateRange(address, size_in_bytes);
|
TextureCache::InvalidateRange(address, size_in_bytes);
|
||||||
|
|
||||||
u16 blkW = TexDecoder_GetBlockWidthInTexels(format) - 1;
|
u16 blkW = TexDecoder_GetBlockWidthInTexels(format) - 1;
|
||||||
u16 blkH = TexDecoder_GetBlockHeightInTexels(format) - 1;
|
u16 blkH = TexDecoder_GetBlockHeightInTexels(format) - 1;
|
||||||
u16 samples = TextureConversionShader::GetEncodedSampleCount(format);
|
u16 samples = TextureConversionShader::GetEncodedSampleCount(format);
|
||||||
|
|
||||||
// only copy on cache line boundaries
|
// only copy on cache line boundaries
|
||||||
// extra pixels are copied but not displayed in the resulting texture
|
// extra pixels are copied but not displayed in the resulting texture
|
||||||
s32 expandedWidth = (width + blkW) & (~blkW);
|
s32 expandedWidth = (width + blkW) & (~blkW);
|
||||||
s32 expandedHeight = (height + blkH) & (~blkH);
|
s32 expandedHeight = (height + blkH) & (~blkH);
|
||||||
|
|
||||||
float MValueX = Renderer::GetTargetScaleX();
|
float MValueX = Renderer::GetTargetScaleX();
|
||||||
float MValueY = Renderer::GetTargetScaleY();
|
float MValueY = Renderer::GetTargetScaleY();
|
||||||
|
|
||||||
float top = (EFB_HEIGHT - source.top - expandedHeight) * MValueY ;
|
float top = (EFB_HEIGHT - source.top - expandedHeight) * MValueY ;
|
||||||
|
|
||||||
float sampleStride = bScaleByHalf?2.0f:1.0f;
|
float sampleStride = bScaleByHalf?2.0f:1.0f;
|
||||||
|
|
||||||
TextureConversionShader::SetShaderParameters((float)expandedWidth,
|
TextureConversionShader::SetShaderParameters((float)expandedWidth,
|
||||||
expandedHeight * MValueY,
|
expandedHeight * MValueY,
|
||||||
source.left * MValueX,
|
source.left * MValueX,
|
||||||
top,
|
top,
|
||||||
sampleStride * MValueX,
|
sampleStride * MValueX,
|
||||||
sampleStride * MValueY);
|
sampleStride * MValueY);
|
||||||
|
|
||||||
TargetRectangle scaledSource;
|
TargetRectangle scaledSource;
|
||||||
scaledSource.top = 0;
|
scaledSource.top = 0;
|
||||||
scaledSource.bottom = expandedHeight;
|
scaledSource.bottom = expandedHeight;
|
||||||
scaledSource.left = 0;
|
scaledSource.left = 0;
|
||||||
scaledSource.right = expandedWidth / samples;
|
scaledSource.right = expandedWidth / samples;
|
||||||
|
|
||||||
|
|
||||||
int cacheBytes = 32;
|
int cacheBytes = 32;
|
||||||
if ((format & 0x0f) == 6)
|
if ((format & 0x0f) == 6)
|
||||||
cacheBytes = 64;
|
cacheBytes = 64;
|
||||||
|
|
||||||
int readStride = (expandedWidth * cacheBytes) / TexDecoder_GetBlockWidthInTexels(format);
|
int readStride = (expandedWidth * cacheBytes) / TexDecoder_GetBlockWidthInTexels(format);
|
||||||
g_renderer->ResetAPIState();
|
g_renderer->ResetAPIState();
|
||||||
EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0);
|
EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0);
|
||||||
FramebufferManager::SetFramebuffer(0);
|
FramebufferManager::SetFramebuffer(0);
|
||||||
VertexShaderManager::SetViewportChanged();
|
VertexShaderManager::SetViewportChanged();
|
||||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
|
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
|
||||||
TextureCache::DisableStage(0);
|
TextureCache::DisableStage(0);
|
||||||
g_renderer->RestoreAPIState();
|
g_renderer->RestoreAPIState();
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
u64 EncodeToRamFromTexture(u32 address,GLuint source_texture,float MValueX,float MValueY,bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source)
|
u64 EncodeToRamFromTexture(u32 address,GLuint source_texture,float MValueX,float MValueY,bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source)
|
||||||
{
|
{
|
||||||
u32 format = copyfmt;
|
u32 format = copyfmt;
|
||||||
|
|
||||||
if (bFromZBuffer)
|
if (bFromZBuffer)
|
||||||
{
|
{
|
||||||
format |= _GX_TF_ZTF;
|
format |= _GX_TF_ZTF;
|
||||||
if (copyfmt == 11)
|
if (copyfmt == 11)
|
||||||
format = GX_TF_Z16;
|
format = GX_TF_Z16;
|
||||||
else if (format < GX_TF_Z8 || format > GX_TF_Z24X8)
|
else if (format < GX_TF_Z8 || format > GX_TF_Z24X8)
|
||||||
format |= _GX_TF_CTF;
|
format |= _GX_TF_CTF;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if (copyfmt > GX_TF_RGBA8 || (copyfmt < GX_TF_RGB565 && !bIsIntensityFmt))
|
if (copyfmt > GX_TF_RGBA8 || (copyfmt < GX_TF_RGB565 && !bIsIntensityFmt))
|
||||||
format |= _GX_TF_CTF;
|
format |= _GX_TF_CTF;
|
||||||
|
|
||||||
FRAGMENTSHADER& texconv_shader = GetOrCreateEncodingShader(format);
|
FRAGMENTSHADER& texconv_shader = GetOrCreateEncodingShader(format);
|
||||||
if (texconv_shader.glprogid == 0)
|
if (texconv_shader.glprogid == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
u8 *dest_ptr = Memory_GetPtr(address);
|
u8 *dest_ptr = Memory_GetPtr(address);
|
||||||
|
|
||||||
int width = (source.right - source.left) >> bScaleByHalf;
|
int width = (source.right - source.left) >> bScaleByHalf;
|
||||||
int height = (source.bottom - source.top) >> bScaleByHalf;
|
int height = (source.bottom - source.top) >> bScaleByHalf;
|
||||||
|
|
||||||
int size_in_bytes = TexDecoder_GetTextureSizeInBytes(width, height, format);
|
int size_in_bytes = TexDecoder_GetTextureSizeInBytes(width, height, format);
|
||||||
|
|
||||||
u16 blkW = TexDecoder_GetBlockWidthInTexels(format) - 1;
|
u16 blkW = TexDecoder_GetBlockWidthInTexels(format) - 1;
|
||||||
u16 blkH = TexDecoder_GetBlockHeightInTexels(format) - 1;
|
u16 blkH = TexDecoder_GetBlockHeightInTexels(format) - 1;
|
||||||
u16 samples = TextureConversionShader::GetEncodedSampleCount(format);
|
u16 samples = TextureConversionShader::GetEncodedSampleCount(format);
|
||||||
|
|
||||||
// only copy on cache line boundaries
|
// only copy on cache line boundaries
|
||||||
// extra pixels are copied but not displayed in the resulting texture
|
// extra pixels are copied but not displayed in the resulting texture
|
||||||
s32 expandedWidth = (width + blkW) & (~blkW);
|
s32 expandedWidth = (width + blkW) & (~blkW);
|
||||||
s32 expandedHeight = (height + blkH) & (~blkH);
|
s32 expandedHeight = (height + blkH) & (~blkH);
|
||||||
|
|
||||||
float sampleStride = bScaleByHalf?2.0f:1.0f;
|
float sampleStride = bScaleByHalf?2.0f:1.0f;
|
||||||
float top = (EFB_HEIGHT - source.top - expandedHeight) * MValueY ;
|
float top = (EFB_HEIGHT - source.top - expandedHeight) * MValueY ;
|
||||||
TextureConversionShader::SetShaderParameters((float)expandedWidth,
|
TextureConversionShader::SetShaderParameters((float)expandedWidth,
|
||||||
expandedHeight * MValueY,
|
expandedHeight * MValueY,
|
||||||
source.left * MValueX,
|
source.left * MValueX,
|
||||||
top,
|
top,
|
||||||
sampleStride * MValueX,
|
sampleStride * MValueX,
|
||||||
sampleStride * MValueY);
|
sampleStride * MValueY);
|
||||||
|
|
||||||
TargetRectangle scaledSource;
|
TargetRectangle scaledSource;
|
||||||
scaledSource.top = 0;
|
scaledSource.top = 0;
|
||||||
scaledSource.bottom = expandedHeight;
|
scaledSource.bottom = expandedHeight;
|
||||||
scaledSource.left = 0;
|
scaledSource.left = 0;
|
||||||
scaledSource.right = expandedWidth / samples;
|
scaledSource.right = expandedWidth / samples;
|
||||||
|
|
||||||
|
|
||||||
int cacheBytes = 32;
|
int cacheBytes = 32;
|
||||||
if ((format & 0x0f) == 6)
|
if ((format & 0x0f) == 6)
|
||||||
cacheBytes = 64;
|
cacheBytes = 64;
|
||||||
|
|
||||||
int readStride = (expandedWidth * cacheBytes) / TexDecoder_GetBlockWidthInTexels(format);
|
int readStride = (expandedWidth * cacheBytes) / TexDecoder_GetBlockWidthInTexels(format);
|
||||||
|
|
||||||
EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0 && !bFromZBuffer);
|
EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0 && !bFromZBuffer);
|
||||||
g_texture_cache->MakeRangeDynamic(address,size_in_bytes);
|
g_texture_cache->MakeRangeDynamic(address,size_in_bytes);
|
||||||
return GetHash64(dest_ptr,size_in_bytes,g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
return GetHash64(dest_ptr,size_in_bytes,g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EncodeToRamYUYV(GLuint srcTexture, const TargetRectangle& sourceRc,
|
void EncodeToRamYUYV(GLuint srcTexture, const TargetRectangle& sourceRc,
|
||||||
u8* destAddr, int dstWidth, int dstHeight)
|
u8* destAddr, int dstWidth, int dstHeight)
|
||||||
{
|
{
|
||||||
g_renderer->ResetAPIState();
|
g_renderer->ResetAPIState();
|
||||||
EncodeToRamUsingShader(s_rgbToYuyvProgram, srcTexture, sourceRc, destAddr, dstWidth / 2, dstHeight, 0, false, false);
|
EncodeToRamUsingShader(s_rgbToYuyvProgram, srcTexture, sourceRc, destAddr, dstWidth / 2, dstHeight, 0, false, false);
|
||||||
FramebufferManager::SetFramebuffer(0);
|
FramebufferManager::SetFramebuffer(0);
|
||||||
VertexShaderManager::SetViewportChanged();
|
VertexShaderManager::SetViewportChanged();
|
||||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
|
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
|
||||||
TextureCache::DisableStage(0);
|
TextureCache::DisableStage(0);
|
||||||
g_renderer->RestoreAPIState();
|
g_renderer->RestoreAPIState();
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Should be scale free.
|
// Should be scale free.
|
||||||
void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTexture)
|
void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTexture)
|
||||||
{
|
{
|
||||||
u8* srcAddr = Memory_GetPtr(xfbAddr);
|
u8* srcAddr = Memory_GetPtr(xfbAddr);
|
||||||
if (!srcAddr)
|
if (!srcAddr)
|
||||||
{
|
{
|
||||||
WARN_LOG(VIDEO, "Tried to decode from invalid memory address");
|
WARN_LOG(VIDEO, "Tried to decode from invalid memory address");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_renderer->ResetAPIState();
|
g_renderer->ResetAPIState();
|
||||||
|
|
||||||
int srcFmtWidth = srcWidth / 2;
|
int srcFmtWidth = srcWidth / 2;
|
||||||
|
|
||||||
// swich to texture converter frame buffer
|
// swich to texture converter frame buffer
|
||||||
// attach destTexture as color destination
|
// attach destTexture as color destination
|
||||||
FramebufferManager::SetFramebuffer(s_texConvFrameBuffer);
|
FramebufferManager::SetFramebuffer(s_texConvFrameBuffer);
|
||||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, destTexture);
|
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, destTexture);
|
||||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, destTexture, 0);
|
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, destTexture, 0);
|
||||||
|
|
||||||
GL_REPORT_FBO_ERROR();
|
GL_REPORT_FBO_ERROR();
|
||||||
|
|
||||||
for (int i = 1; i < 8; ++i)
|
for (int i = 1; i < 8; ++i)
|
||||||
TextureCache::DisableStage(i);
|
TextureCache::DisableStage(i);
|
||||||
|
|
||||||
// activate source texture
|
// activate source texture
|
||||||
// set srcAddr as data for source texture
|
// set srcAddr as data for source texture
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glEnable(GL_TEXTURE_RECTANGLE_ARB);
|
glEnable(GL_TEXTURE_RECTANGLE_ARB);
|
||||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, s_srcTexture);
|
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, s_srcTexture);
|
||||||
|
|
||||||
// TODO: make this less slow. (How?)
|
// TODO: make this less slow. (How?)
|
||||||
if((GLsizei)s_srcTextureWidth == (GLsizei)srcFmtWidth && (GLsizei)s_srcTextureHeight == (GLsizei)srcHeight)
|
if((GLsizei)s_srcTextureWidth == (GLsizei)srcFmtWidth && (GLsizei)s_srcTextureHeight == (GLsizei)srcHeight)
|
||||||
{
|
{
|
||||||
glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0,0,0,s_srcTextureWidth, s_srcTextureHeight, GL_BGRA, GL_UNSIGNED_BYTE, srcAddr);
|
glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0,0,0,s_srcTextureWidth, s_srcTextureHeight, GL_BGRA, GL_UNSIGNED_BYTE, srcAddr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, (GLsizei)srcFmtWidth, (GLsizei)srcHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, srcAddr);
|
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, (GLsizei)srcFmtWidth, (GLsizei)srcHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, srcAddr);
|
||||||
s_srcTextureWidth = (GLsizei)srcFmtWidth;
|
s_srcTextureWidth = (GLsizei)srcFmtWidth;
|
||||||
s_srcTextureHeight = (GLsizei)srcHeight;
|
s_srcTextureHeight = (GLsizei)srcHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
glViewport(0, 0, srcWidth, srcHeight);
|
glViewport(0, 0, srcWidth, srcHeight);
|
||||||
|
|
||||||
PixelShaderCache::SetCurrentShader(s_yuyvToRgbProgram.glprogid);
|
PixelShaderCache::SetCurrentShader(s_yuyvToRgbProgram.glprogid);
|
||||||
|
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
glBegin(GL_QUADS);
|
glBegin(GL_QUADS);
|
||||||
glTexCoord2f((float)srcFmtWidth, (float)srcHeight);
|
glTexCoord2f((float)srcFmtWidth, (float)srcHeight);
|
||||||
glVertex2f(1, -1);
|
glVertex2f(1, -1);
|
||||||
glTexCoord2f((float)srcFmtWidth, 0);
|
glTexCoord2f((float)srcFmtWidth, 0);
|
||||||
glVertex2f(1, 1);
|
glVertex2f(1, 1);
|
||||||
glTexCoord2f(0, 0);
|
glTexCoord2f(0, 0);
|
||||||
glVertex2f(-1, 1);
|
glVertex2f(-1, 1);
|
||||||
glTexCoord2f(0, (float)srcHeight);
|
glTexCoord2f(0, (float)srcHeight);
|
||||||
glVertex2f(-1, -1);
|
glVertex2f(-1, -1);
|
||||||
glEnd();
|
glEnd();
|
||||||
|
|
||||||
// reset state
|
// reset state
|
||||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
|
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
|
||||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, 0, 0);
|
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, 0, 0);
|
||||||
TextureCache::DisableStage(0);
|
TextureCache::DisableStage(0);
|
||||||
|
|
||||||
VertexShaderManager::SetViewportChanged();
|
VertexShaderManager::SetViewportChanged();
|
||||||
|
|
||||||
FramebufferManager::SetFramebuffer(0);
|
FramebufferManager::SetFramebuffer(0);
|
||||||
|
|
||||||
g_renderer->RestoreAPIState();
|
g_renderer->RestoreAPIState();
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,50 +1,50 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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/
|
||||||
|
|
||||||
#ifndef _OGL_TEXTURECONVERTER_H_
|
#ifndef _OGL_TEXTURECONVERTER_H_
|
||||||
#define _OGL_TEXTURECONVERTER_H_
|
#define _OGL_TEXTURECONVERTER_H_
|
||||||
|
|
||||||
#include "VideoCommon.h"
|
#include "VideoCommon.h"
|
||||||
|
|
||||||
#include "OGL_GLUtil.h"
|
#include "OGL_GLUtil.h"
|
||||||
|
|
||||||
namespace OGL
|
namespace OGL
|
||||||
{
|
{
|
||||||
|
|
||||||
// Converts textures between formats
|
// Converts textures between formats
|
||||||
// TODO: support multiple texture formats
|
// TODO: support multiple texture formats
|
||||||
namespace TextureConverter
|
namespace TextureConverter
|
||||||
{
|
{
|
||||||
|
|
||||||
void Init();
|
void Init();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
|
||||||
void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt,
|
void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt,
|
||||||
u32 copyfmt, int bScaleByHalf, const EFBRectangle& source);
|
u32 copyfmt, int bScaleByHalf, const EFBRectangle& source);
|
||||||
|
|
||||||
void EncodeToRamYUYV(GLuint srcTexture, const TargetRectangle& sourceRc,
|
void EncodeToRamYUYV(GLuint srcTexture, const TargetRectangle& sourceRc,
|
||||||
u8* destAddr, int dstWidth, int dstHeight);
|
u8* destAddr, int dstWidth, int dstHeight);
|
||||||
|
|
||||||
void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTexture);
|
void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTexture);
|
||||||
|
|
||||||
u64 EncodeToRamFromTexture(u32 address,GLuint source_texture,float MValueX,float MValueY, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source);
|
u64 EncodeToRamFromTexture(u32 address,GLuint source_texture,float MValueX,float MValueY, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // _TEXTURECONVERTER_H_
|
#endif // _TEXTURECONVERTER_H_
|
||||||
|
|||||||
@@ -1,113 +1,113 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
// Common
|
// Common
|
||||||
#include "MemoryUtil.h"
|
#include "MemoryUtil.h"
|
||||||
#include "FileUtil.h"
|
#include "FileUtil.h"
|
||||||
|
|
||||||
// VideoCommon
|
// VideoCommon
|
||||||
#include "Fifo.h"
|
#include "Fifo.h"
|
||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
#include "Statistics.h"
|
#include "Statistics.h"
|
||||||
#include "Profiler.h"
|
#include "Profiler.h"
|
||||||
#include "ImageWrite.h"
|
#include "ImageWrite.h"
|
||||||
#include "BPMemory.h"
|
#include "BPMemory.h"
|
||||||
#include "IndexGenerator.h"
|
#include "IndexGenerator.h"
|
||||||
#include "OpcodeDecoding.h"
|
#include "OpcodeDecoding.h"
|
||||||
#include "PixelShaderManager.h"
|
#include "PixelShaderManager.h"
|
||||||
#include "VertexShaderManager.h"
|
#include "VertexShaderManager.h"
|
||||||
#include "VertexShaderGen.h"
|
#include "VertexShaderGen.h"
|
||||||
#include "VertexLoader.h"
|
#include "VertexLoader.h"
|
||||||
|
|
||||||
// OGL
|
// OGL
|
||||||
#include "OGL_Render.h"
|
#include "OGL_Render.h"
|
||||||
#include "OGL_TextureCache.h"
|
#include "OGL_TextureCache.h"
|
||||||
#include "OGL_PixelShaderCache.h"
|
#include "OGL_PixelShaderCache.h"
|
||||||
#include "OGL_VertexShaderCache.h"
|
#include "OGL_VertexShaderCache.h"
|
||||||
#include "OGL_VertexManager.h"
|
#include "OGL_VertexManager.h"
|
||||||
|
|
||||||
#include "../Main.h"
|
#include "../Main.h"
|
||||||
|
|
||||||
namespace OGL
|
namespace OGL
|
||||||
{
|
{
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
MAXVBUFFERSIZE = 0x1FFFF,
|
MAXVBUFFERSIZE = 0x1FFFF,
|
||||||
MAXIBUFFERSIZE = 0xFFFF,
|
MAXIBUFFERSIZE = 0xFFFF,
|
||||||
MAXVBOBUFFERCOUNT = 0x8,
|
MAXVBOBUFFERCOUNT = 0x8,
|
||||||
};
|
};
|
||||||
|
|
||||||
//static GLuint s_vboBuffers[MAXVBOBUFFERCOUNT] = {0};
|
//static GLuint s_vboBuffers[MAXVBOBUFFERCOUNT] = {0};
|
||||||
//static int s_nCurVBOIndex = 0; // current free buffer
|
//static int s_nCurVBOIndex = 0; // current free buffer
|
||||||
|
|
||||||
VertexManager::VertexManager()
|
VertexManager::VertexManager()
|
||||||
{
|
{
|
||||||
lastPrimitive = GX_DRAW_NONE;
|
lastPrimitive = GX_DRAW_NONE;
|
||||||
|
|
||||||
//s_nCurVBOIndex = 0;
|
//s_nCurVBOIndex = 0;
|
||||||
//glGenBuffers(ARRAYSIZE(s_vboBuffers), s_vboBuffers);
|
//glGenBuffers(ARRAYSIZE(s_vboBuffers), s_vboBuffers);
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
g_nativeVertexFmt = NULL;
|
g_nativeVertexFmt = NULL;
|
||||||
|
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
}
|
}
|
||||||
|
|
||||||
VertexManager::~VertexManager()
|
VertexManager::~VertexManager()
|
||||||
{
|
{
|
||||||
//glDeleteBuffers(ARRAYSIZE(s_vboBuffers), s_vboBuffers);
|
//glDeleteBuffers(ARRAYSIZE(s_vboBuffers), s_vboBuffers);
|
||||||
//s_nCurVBOIndex = 0;
|
//s_nCurVBOIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexManager::Draw(u32 /*stride*/, bool alphapass)
|
void VertexManager::Draw(u32 /*stride*/, bool alphapass)
|
||||||
{
|
{
|
||||||
if (alphapass)
|
if (alphapass)
|
||||||
{
|
{
|
||||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
|
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IndexGenerator::GetNumTriangles() > 0)
|
if (IndexGenerator::GetNumTriangles() > 0)
|
||||||
{
|
{
|
||||||
glDrawElements(GL_TRIANGLES, IndexGenerator::GetTriangleindexLen(), GL_UNSIGNED_SHORT, TIBuffer);
|
glDrawElements(GL_TRIANGLES, IndexGenerator::GetTriangleindexLen(), GL_UNSIGNED_SHORT, TIBuffer);
|
||||||
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
|
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
|
||||||
}
|
}
|
||||||
if (IndexGenerator::GetNumLines() > 0)
|
if (IndexGenerator::GetNumLines() > 0)
|
||||||
{
|
{
|
||||||
glDrawElements(GL_LINES, IndexGenerator::GetLineindexLen(), GL_UNSIGNED_SHORT, LIBuffer);
|
glDrawElements(GL_LINES, IndexGenerator::GetLineindexLen(), GL_UNSIGNED_SHORT, LIBuffer);
|
||||||
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
|
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
|
||||||
}
|
}
|
||||||
if (IndexGenerator::GetNumPoints() > 0)
|
if (IndexGenerator::GetNumPoints() > 0)
|
||||||
{
|
{
|
||||||
glDrawElements(GL_POINTS, IndexGenerator::GetPointindexLen(), GL_UNSIGNED_SHORT, PIBuffer);
|
glDrawElements(GL_POINTS, IndexGenerator::GetPointindexLen(), GL_UNSIGNED_SHORT, PIBuffer);
|
||||||
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
|
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (alphapass)
|
if (alphapass)
|
||||||
{
|
{
|
||||||
// restore color mask
|
// restore color mask
|
||||||
g_renderer->SetColorMask();
|
g_renderer->SetColorMask();
|
||||||
|
|
||||||
if (bpmem.blendmode.blendenable || bpmem.blendmode.subtract)
|
if (bpmem.blendmode.blendenable || bpmem.blendmode.subtract)
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,44 +1,44 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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/
|
||||||
|
|
||||||
#ifndef _OGL_VERTEXMANAGER_H_
|
#ifndef _OGL_VERTEXMANAGER_H_
|
||||||
#define _OGL_VERTEXMANAGER_H_
|
#define _OGL_VERTEXMANAGER_H_
|
||||||
|
|
||||||
#include "CPMemory.h"
|
#include "CPMemory.h"
|
||||||
#include "NativeVertexWriter.h"
|
#include "NativeVertexWriter.h"
|
||||||
|
|
||||||
#include "../VertexManager.h"
|
#include "../VertexManager.h"
|
||||||
|
|
||||||
namespace OGL
|
namespace OGL
|
||||||
{
|
{
|
||||||
|
|
||||||
// Handles the OpenGL details of drawing lots of vertices quickly.
|
// Handles the OpenGL details of drawing lots of vertices quickly.
|
||||||
// Other functionality is moving out.
|
// Other functionality is moving out.
|
||||||
class VertexManager : public ::VertexManagerBase
|
class VertexManager : public ::VertexManagerBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
VertexManager();
|
VertexManager();
|
||||||
~VertexManager();
|
~VertexManager();
|
||||||
|
|
||||||
void Draw(u32 stride, bool alphapass);
|
void Draw(u32 stride, bool alphapass);
|
||||||
|
|
||||||
NativeVertexFormat* CreateNativeVertexFormat();
|
NativeVertexFormat* CreateNativeVertexFormat();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // _VERTEXMANAGER_H_
|
#endif // _VERTEXMANAGER_H_
|
||||||
|
|||||||
@@ -1,255 +1,255 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
// Common
|
// Common
|
||||||
#include "FileUtil.h"
|
#include "FileUtil.h"
|
||||||
|
|
||||||
// VideoCommon
|
// VideoCommon
|
||||||
#include "Profiler.h"
|
#include "Profiler.h"
|
||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
#include "Statistics.h"
|
#include "Statistics.h"
|
||||||
#include "VertexShaderGen.h"
|
#include "VertexShaderGen.h"
|
||||||
#include "VertexShaderManager.h"
|
#include "VertexShaderManager.h"
|
||||||
#include "VertexLoader.h"
|
#include "VertexLoader.h"
|
||||||
#include "XFMemory.h"
|
#include "XFMemory.h"
|
||||||
#include "ImageWrite.h"
|
#include "ImageWrite.h"
|
||||||
|
|
||||||
// OGL
|
// OGL
|
||||||
#include "OGL_Render.h"
|
#include "OGL_Render.h"
|
||||||
#include "OGL_VertexShaderCache.h"
|
#include "OGL_VertexShaderCache.h"
|
||||||
#include "OGL_GLUtil.h"
|
#include "OGL_GLUtil.h"
|
||||||
#include "OGL_VertexManager.h"
|
#include "OGL_VertexManager.h"
|
||||||
|
|
||||||
#include "../Main.h"
|
#include "../Main.h"
|
||||||
|
|
||||||
namespace OGL
|
namespace OGL
|
||||||
{
|
{
|
||||||
|
|
||||||
VertexShaderCache::VSCache VertexShaderCache::vshaders;
|
VertexShaderCache::VSCache VertexShaderCache::vshaders;
|
||||||
bool VertexShaderCache::s_displayCompileAlert;
|
bool VertexShaderCache::s_displayCompileAlert;
|
||||||
GLuint VertexShaderCache::CurrentShader;
|
GLuint VertexShaderCache::CurrentShader;
|
||||||
bool VertexShaderCache::ShaderEnabled;
|
bool VertexShaderCache::ShaderEnabled;
|
||||||
|
|
||||||
static VERTEXSHADER *pShaderLast = NULL;
|
static VERTEXSHADER *pShaderLast = NULL;
|
||||||
static int s_nMaxVertexInstructions;
|
static int s_nMaxVertexInstructions;
|
||||||
|
|
||||||
void VertexShaderCache::SetVSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4)
|
void VertexShaderCache::SetVSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4)
|
||||||
{
|
{
|
||||||
float f[4] = { f1, f2, f3, f4 };
|
float f[4] = { f1, f2, f3, f4 };
|
||||||
glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, const_number, f);
|
glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, const_number, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexShaderCache::SetVSConstant4fv(unsigned int const_number, const float *f)
|
void VertexShaderCache::SetVSConstant4fv(unsigned int const_number, const float *f)
|
||||||
{
|
{
|
||||||
glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, const_number, f);
|
glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, const_number, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexShaderCache::SetMultiVSConstant4fv(unsigned int const_number, unsigned int count, const float *f)
|
void VertexShaderCache::SetMultiVSConstant4fv(unsigned int const_number, unsigned int count, const float *f)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < count; i++,f+=4)
|
for (unsigned int i = 0; i < count; i++,f+=4)
|
||||||
glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, const_number + i, f);
|
glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, const_number + i, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexShaderCache::SetMultiVSConstant3fv(unsigned int const_number, unsigned int count, const float *f)
|
void VertexShaderCache::SetMultiVSConstant3fv(unsigned int const_number, unsigned int count, const float *f)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
float buf[4];
|
float buf[4];
|
||||||
buf[0] = *f++;
|
buf[0] = *f++;
|
||||||
buf[1] = *f++;
|
buf[1] = *f++;
|
||||||
buf[2] = *f++;
|
buf[2] = *f++;
|
||||||
buf[3] = 0.f;
|
buf[3] = 0.f;
|
||||||
glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, const_number + i, buf);
|
glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, const_number + i, buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VertexShaderCache::VertexShaderCache()
|
VertexShaderCache::VertexShaderCache()
|
||||||
{
|
{
|
||||||
glEnable(GL_VERTEX_PROGRAM_ARB);
|
glEnable(GL_VERTEX_PROGRAM_ARB);
|
||||||
ShaderEnabled = true;
|
ShaderEnabled = true;
|
||||||
CurrentShader = 0;
|
CurrentShader = 0;
|
||||||
memset(&last_vertex_shader_uid, 0xFF, sizeof(last_vertex_shader_uid));
|
memset(&last_vertex_shader_uid, 0xFF, sizeof(last_vertex_shader_uid));
|
||||||
|
|
||||||
s_displayCompileAlert = true;
|
s_displayCompileAlert = true;
|
||||||
|
|
||||||
glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, (GLint *)&s_nMaxVertexInstructions);
|
glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, (GLint *)&s_nMaxVertexInstructions);
|
||||||
#if CG_VERSION_NUM == 2100
|
#if CG_VERSION_NUM == 2100
|
||||||
if (strstr((const char*)glGetString(GL_VENDOR), "ATI") != NULL)
|
if (strstr((const char*)glGetString(GL_VENDOR), "ATI") != NULL)
|
||||||
{
|
{
|
||||||
s_nMaxVertexInstructions = 4096;
|
s_nMaxVertexInstructions = 4096;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
VertexShaderCache::~VertexShaderCache()
|
VertexShaderCache::~VertexShaderCache()
|
||||||
{
|
{
|
||||||
for (VSCache::iterator iter = vshaders.begin(); iter != vshaders.end(); iter++)
|
for (VSCache::iterator iter = vshaders.begin(); iter != vshaders.end(); iter++)
|
||||||
iter->second.Destroy();
|
iter->second.Destroy();
|
||||||
vshaders.clear();
|
vshaders.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VertexShaderCache::SetShader(u32 components)
|
bool VertexShaderCache::SetShader(u32 components)
|
||||||
{
|
{
|
||||||
const VERTEXSHADER* const vs = GetShader(components);
|
const VERTEXSHADER* const vs = GetShader(components);
|
||||||
if (vs)
|
if (vs)
|
||||||
{
|
{
|
||||||
SetCurrentShader(vs->glprogid);
|
SetCurrentShader(vs->glprogid);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
VERTEXSHADER* VertexShaderCache::GetShader(u32 components)
|
VERTEXSHADER* VertexShaderCache::GetShader(u32 components)
|
||||||
{
|
{
|
||||||
DVSTARTPROFILE();
|
DVSTARTPROFILE();
|
||||||
VERTEXSHADERUID uid;
|
VERTEXSHADERUID uid;
|
||||||
GetVertexShaderId(&uid, components);
|
GetVertexShaderId(&uid, components);
|
||||||
|
|
||||||
if (uid == last_vertex_shader_uid && vshaders[uid].frameCount == frameCount)
|
if (uid == last_vertex_shader_uid && vshaders[uid].frameCount == frameCount)
|
||||||
{
|
{
|
||||||
return pShaderLast;
|
return pShaderLast;
|
||||||
}
|
}
|
||||||
memcpy(&last_vertex_shader_uid, &uid, sizeof(VERTEXSHADERUID));
|
memcpy(&last_vertex_shader_uid, &uid, sizeof(VERTEXSHADERUID));
|
||||||
|
|
||||||
VSCache::iterator iter = vshaders.find(uid);
|
VSCache::iterator iter = vshaders.find(uid);
|
||||||
|
|
||||||
if (iter != vshaders.end()) {
|
if (iter != vshaders.end()) {
|
||||||
iter->second.frameCount = frameCount;
|
iter->second.frameCount = frameCount;
|
||||||
VSCacheEntry &entry = iter->second;
|
VSCacheEntry &entry = iter->second;
|
||||||
if (&entry.shader != pShaderLast) {
|
if (&entry.shader != pShaderLast) {
|
||||||
pShaderLast = &entry.shader;
|
pShaderLast = &entry.shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pShaderLast;
|
return pShaderLast;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Make an entry in the table
|
//Make an entry in the table
|
||||||
VSCacheEntry& entry = vshaders[uid];
|
VSCacheEntry& entry = vshaders[uid];
|
||||||
entry.frameCount = frameCount;
|
entry.frameCount = frameCount;
|
||||||
pShaderLast = &entry.shader;
|
pShaderLast = &entry.shader;
|
||||||
const char *code = GenerateVertexShaderCode(components, API_OPENGL);
|
const char *code = GenerateVertexShaderCode(components, API_OPENGL);
|
||||||
|
|
||||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||||
if (g_ActiveConfig.iLog & CONF_SAVESHADERS && code) {
|
if (g_ActiveConfig.iLog & CONF_SAVESHADERS && code) {
|
||||||
static int counter = 0;
|
static int counter = 0;
|
||||||
char szTemp[MAX_PATH];
|
char szTemp[MAX_PATH];
|
||||||
sprintf(szTemp, "%svs_%04i.txt", File::GetUserPath(D_DUMP_IDX), counter++);
|
sprintf(szTemp, "%svs_%04i.txt", File::GetUserPath(D_DUMP_IDX), counter++);
|
||||||
|
|
||||||
SaveData(szTemp, code);
|
SaveData(szTemp, code);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!code || !VertexShaderCache::CompileVertexShader(entry.shader, code)) {
|
if (!code || !VertexShaderCache::CompileVertexShader(entry.shader, code)) {
|
||||||
ERROR_LOG(VIDEO, "failed to create vertex shader");
|
ERROR_LOG(VIDEO, "failed to create vertex shader");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
INCSTAT(stats.numVertexShadersCreated);
|
INCSTAT(stats.numVertexShadersCreated);
|
||||||
SETSTAT(stats.numVertexShadersAlive, vshaders.size());
|
SETSTAT(stats.numVertexShadersAlive, vshaders.size());
|
||||||
return pShaderLast;
|
return pShaderLast;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VertexShaderCache::CompileVertexShader(VERTEXSHADER& vs, const char* pstrprogram)
|
bool VertexShaderCache::CompileVertexShader(VERTEXSHADER& vs, const char* pstrprogram)
|
||||||
{
|
{
|
||||||
// Reset GL error before compiling shaders. Yeah, we need to investigate the causes of these.
|
// Reset GL error before compiling shaders. Yeah, we need to investigate the causes of these.
|
||||||
GLenum err = GL_REPORT_ERROR();
|
GLenum err = GL_REPORT_ERROR();
|
||||||
if (err != GL_NO_ERROR)
|
if (err != GL_NO_ERROR)
|
||||||
{
|
{
|
||||||
ERROR_LOG(VIDEO, "glError %08x before VS!", err);
|
ERROR_LOG(VIDEO, "glError %08x before VS!", err);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined HAVE_CG && HAVE_CG
|
#if defined HAVE_CG && HAVE_CG
|
||||||
char stropt[64];
|
char stropt[64];
|
||||||
sprintf(stropt, "MaxLocalParams=256,MaxInstructions=%d", s_nMaxVertexInstructions);
|
sprintf(stropt, "MaxLocalParams=256,MaxInstructions=%d", s_nMaxVertexInstructions);
|
||||||
const char *opts[] = {"-profileopts", stropt, "-O2", "-q", NULL};
|
const char *opts[] = {"-profileopts", stropt, "-O2", "-q", NULL};
|
||||||
CGprogram tempprog = cgCreateProgram(g_cgcontext, CG_SOURCE, pstrprogram, g_cgvProf, "main", opts);
|
CGprogram tempprog = cgCreateProgram(g_cgcontext, CG_SOURCE, pstrprogram, g_cgvProf, "main", opts);
|
||||||
if (!cgIsProgram(tempprog)) {
|
if (!cgIsProgram(tempprog)) {
|
||||||
if (s_displayCompileAlert) {
|
if (s_displayCompileAlert) {
|
||||||
PanicAlert("Failed to create vertex shader");
|
PanicAlert("Failed to create vertex shader");
|
||||||
s_displayCompileAlert = false;
|
s_displayCompileAlert = false;
|
||||||
}
|
}
|
||||||
cgDestroyProgram(tempprog);
|
cgDestroyProgram(tempprog);
|
||||||
ERROR_LOG(VIDEO, "Failed to load vs %s:", cgGetLastListing(g_cgcontext));
|
ERROR_LOG(VIDEO, "Failed to load vs %s:", cgGetLastListing(g_cgcontext));
|
||||||
ERROR_LOG(VIDEO, pstrprogram);
|
ERROR_LOG(VIDEO, pstrprogram);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cgGetError() != CG_NO_ERROR)
|
if (cgGetError() != CG_NO_ERROR)
|
||||||
{
|
{
|
||||||
WARN_LOG(VIDEO, "Failed to load vs %s:", cgGetLastListing(g_cgcontext));
|
WARN_LOG(VIDEO, "Failed to load vs %s:", cgGetLastListing(g_cgcontext));
|
||||||
WARN_LOG(VIDEO, pstrprogram);
|
WARN_LOG(VIDEO, pstrprogram);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This looks evil - we modify the program through the const char * we got from cgGetProgramString!
|
// This looks evil - we modify the program through the const char * we got from cgGetProgramString!
|
||||||
// It SHOULD not have any nasty side effects though - but you never know...
|
// It SHOULD not have any nasty side effects though - but you never know...
|
||||||
char *pcompiledprog = (char*)cgGetProgramString(tempprog, CG_COMPILED_PROGRAM);
|
char *pcompiledprog = (char*)cgGetProgramString(tempprog, CG_COMPILED_PROGRAM);
|
||||||
char *plocal = strstr(pcompiledprog, "program.local");
|
char *plocal = strstr(pcompiledprog, "program.local");
|
||||||
while (plocal != NULL) {
|
while (plocal != NULL) {
|
||||||
const char* penv = " program.env";
|
const char* penv = " program.env";
|
||||||
memcpy(plocal, penv, 13);
|
memcpy(plocal, penv, 13);
|
||||||
plocal = strstr(plocal + 13, "program.local");
|
plocal = strstr(plocal + 13, "program.local");
|
||||||
}
|
}
|
||||||
glGenProgramsARB(1, &vs.glprogid);
|
glGenProgramsARB(1, &vs.glprogid);
|
||||||
SetCurrentShader(vs.glprogid);
|
SetCurrentShader(vs.glprogid);
|
||||||
|
|
||||||
glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(pcompiledprog), pcompiledprog);
|
glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(pcompiledprog), pcompiledprog);
|
||||||
err = GL_REPORT_ERROR();
|
err = GL_REPORT_ERROR();
|
||||||
if (err != GL_NO_ERROR) {
|
if (err != GL_NO_ERROR) {
|
||||||
ERROR_LOG(VIDEO, pstrprogram);
|
ERROR_LOG(VIDEO, pstrprogram);
|
||||||
ERROR_LOG(VIDEO, pcompiledprog);
|
ERROR_LOG(VIDEO, pcompiledprog);
|
||||||
}
|
}
|
||||||
|
|
||||||
cgDestroyProgram(tempprog);
|
cgDestroyProgram(tempprog);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||||
vs.strprog = pstrprogram;
|
vs.strprog = pstrprogram;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexShaderCache::DisableShader()
|
void VertexShaderCache::DisableShader()
|
||||||
{
|
{
|
||||||
if (ShaderEnabled)
|
if (ShaderEnabled)
|
||||||
{
|
{
|
||||||
glDisable(GL_VERTEX_PROGRAM_ARB);
|
glDisable(GL_VERTEX_PROGRAM_ARB);
|
||||||
ShaderEnabled = false;
|
ShaderEnabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void VertexShaderCache::SetCurrentShader(GLuint Shader)
|
void VertexShaderCache::SetCurrentShader(GLuint Shader)
|
||||||
{
|
{
|
||||||
if (!ShaderEnabled)
|
if (!ShaderEnabled)
|
||||||
{
|
{
|
||||||
glEnable(GL_VERTEX_PROGRAM_ARB);
|
glEnable(GL_VERTEX_PROGRAM_ARB);
|
||||||
ShaderEnabled= true;
|
ShaderEnabled= true;
|
||||||
}
|
}
|
||||||
if (CurrentShader != Shader)
|
if (CurrentShader != Shader)
|
||||||
{
|
{
|
||||||
if(Shader != 0)
|
if(Shader != 0)
|
||||||
CurrentShader = Shader;
|
CurrentShader = Shader;
|
||||||
glBindProgramARB(GL_VERTEX_PROGRAM_ARB, CurrentShader);
|
glBindProgramARB(GL_VERTEX_PROGRAM_ARB, CurrentShader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,89 +1,89 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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/
|
||||||
|
|
||||||
#ifndef _OGL_VERTEXSHADERCACHE_H_
|
#ifndef _OGL_VERTEXSHADERCACHE_H_
|
||||||
#define _OGL_VERTEXSHADERCACHE_H_
|
#define _OGL_VERTEXSHADERCACHE_H_
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
// VideoCommon
|
// VideoCommon
|
||||||
#include "BPMemory.h"
|
#include "BPMemory.h"
|
||||||
#include "VertexShaderGen.h"
|
#include "VertexShaderGen.h"
|
||||||
|
|
||||||
// OGL
|
// OGL
|
||||||
#include "OGL_GLUtil.h"
|
#include "OGL_GLUtil.h"
|
||||||
|
|
||||||
#include "../VertexShaderCache.h"
|
#include "../VertexShaderCache.h"
|
||||||
|
|
||||||
namespace OGL
|
namespace OGL
|
||||||
{
|
{
|
||||||
|
|
||||||
struct VERTEXSHADER
|
struct VERTEXSHADER
|
||||||
{
|
{
|
||||||
VERTEXSHADER() : glprogid(0) {}
|
VERTEXSHADER() : glprogid(0) {}
|
||||||
GLuint glprogid; // opengl program id
|
GLuint glprogid; // opengl program id
|
||||||
|
|
||||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||||
std::string strprog;
|
std::string strprog;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
class VertexShaderCache : public ::VertexShaderCacheBase
|
class VertexShaderCache : public ::VertexShaderCacheBase
|
||||||
{
|
{
|
||||||
struct VSCacheEntry
|
struct VSCacheEntry
|
||||||
{
|
{
|
||||||
VERTEXSHADER shader;
|
VERTEXSHADER shader;
|
||||||
int frameCount;
|
int frameCount;
|
||||||
VSCacheEntry() : frameCount(0) {}
|
VSCacheEntry() : frameCount(0) {}
|
||||||
void Destroy() {
|
void Destroy() {
|
||||||
// printf("Destroying vs %i\n", shader.glprogid);
|
// printf("Destroying vs %i\n", shader.glprogid);
|
||||||
glDeleteProgramsARB(1, &shader.glprogid);
|
glDeleteProgramsARB(1, &shader.glprogid);
|
||||||
shader.glprogid = 0;
|
shader.glprogid = 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<VERTEXSHADERUID, VSCacheEntry> VSCache;
|
typedef std::map<VERTEXSHADERUID, VSCacheEntry> VSCache;
|
||||||
|
|
||||||
static VSCache vshaders;
|
static VSCache vshaders;
|
||||||
|
|
||||||
static bool s_displayCompileAlert;
|
static bool s_displayCompileAlert;
|
||||||
|
|
||||||
static GLuint CurrentShader;
|
static GLuint CurrentShader;
|
||||||
static bool ShaderEnabled;
|
static bool ShaderEnabled;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
VertexShaderCache();
|
VertexShaderCache();
|
||||||
~VertexShaderCache();
|
~VertexShaderCache();
|
||||||
|
|
||||||
bool SetShader(u32 components);
|
bool SetShader(u32 components);
|
||||||
|
|
||||||
static VERTEXSHADER* GetShader(u32 components);
|
static VERTEXSHADER* GetShader(u32 components);
|
||||||
static bool CompileVertexShader(VERTEXSHADER& ps, const char* pstrprogram);
|
static bool CompileVertexShader(VERTEXSHADER& ps, const char* pstrprogram);
|
||||||
|
|
||||||
static void SetCurrentShader(GLuint Shader);
|
static void SetCurrentShader(GLuint Shader);
|
||||||
static void DisableShader();
|
static void DisableShader();
|
||||||
|
|
||||||
void SetVSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4);
|
void SetVSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4);
|
||||||
void SetVSConstant4fv(unsigned int const_number, const float* f);
|
void SetVSConstant4fv(unsigned int const_number, const float* f);
|
||||||
void SetMultiVSConstant3fv(unsigned int const_number, unsigned int count, const float* f);
|
void SetMultiVSConstant3fv(unsigned int const_number, unsigned int count, const float* f);
|
||||||
void SetMultiVSConstant4fv(unsigned int const_number, unsigned int count, const float* f);
|
void SetMultiVSConstant4fv(unsigned int const_number, unsigned int count, const float* f);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // _VERTEXSHADERCACHE_H_
|
#endif // _VERTEXSHADERCACHE_H_
|
||||||
|
|||||||
@@ -1,42 +1,42 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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/
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------------------------
|
||||||
// This file handles the External Frame Buffer (XFB). The XFB is a storage point when the picture is resized
|
// This file handles the External Frame Buffer (XFB). The XFB is a storage point when the picture is resized
|
||||||
// by the system to the correct display format for output to the TV. In most cases its function can be
|
// by the system to the correct display format for output to the TV. In most cases its function can be
|
||||||
// supplemented by the equivalent adjustments in glScissor and glViewport (or their DirectX equivalents). But
|
// supplemented by the equivalent adjustments in glScissor and glViewport (or their DirectX equivalents). But
|
||||||
// for some homebrew games these functions are necessary because the homebrew game communicate directly with
|
// for some homebrew games these functions are necessary because the homebrew game communicate directly with
|
||||||
// them.
|
// them.
|
||||||
// ----------------------------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// OGL
|
// OGL
|
||||||
#include "OGL_Render.h"
|
#include "OGL_Render.h"
|
||||||
#include "OGL_TextureConverter.h"
|
#include "OGL_TextureConverter.h"
|
||||||
#include "OGL_FramebufferManager.h"
|
#include "OGL_FramebufferManager.h"
|
||||||
#include "OGL_XFB.h"
|
#include "OGL_XFB.h"
|
||||||
|
|
||||||
namespace OGL
|
namespace OGL
|
||||||
{
|
{
|
||||||
|
|
||||||
void XFB_Write(u8 *xfb_in_ram, const EFBRectangle& sourceRc, u32 dstWd, u32 dstHt)
|
void XFB_Write(u8 *xfb_in_ram, const EFBRectangle& sourceRc, u32 dstWd, u32 dstHt)
|
||||||
{
|
{
|
||||||
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(sourceRc);
|
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(sourceRc);
|
||||||
TextureConverter::EncodeToRamYUYV(FramebufferManager::ResolveAndGetRenderTarget(sourceRc), targetRc, xfb_in_ram, dstWd, dstHt);
|
TextureConverter::EncodeToRamYUYV(FramebufferManager::ResolveAndGetRenderTarget(sourceRc), targetRc, xfb_in_ram, dstWd, dstHt);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,31 +1,31 @@
|
|||||||
// Copyright (C) 2003 Dolphin Project.
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation, version 2.0.
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License 2.0 for more details.
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
// A copy of the GPL 2.0 should have been included with the program.
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
// If not, see http://www.gnu.org/licenses/
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
// 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/
|
||||||
|
|
||||||
#ifndef _OGL_XFB_H_
|
#ifndef _OGL_XFB_H_
|
||||||
#define _OGL_XFB_H_
|
#define _OGL_XFB_H_
|
||||||
|
|
||||||
#include "OGL_GLUtil.h"
|
#include "OGL_GLUtil.h"
|
||||||
|
|
||||||
namespace OGL
|
namespace OGL
|
||||||
{
|
{
|
||||||
|
|
||||||
// write the EFB to the XFB
|
// write the EFB to the XFB
|
||||||
void XFB_Write(u8 *xfb_in_ram, const EFBRectangle& sourceRc, u32 dstWd, u32 dstHt);
|
void XFB_Write(u8 *xfb_in_ram, const EFBRectangle& sourceRc, u32 dstWd, u32 dstHt);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // _XFB_H_
|
#endif // _XFB_H_
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
|
|
||||||
#include "PixelShaderManager.h"
|
#include "PixelShaderManager.h"
|
||||||
|
|
||||||
#include "Main.h"
|
#include "Main.h"
|
||||||
#include "PixelShaderCache.h"
|
#include "PixelShaderCache.h"
|
||||||
|
|
||||||
void SetPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4)
|
void SetPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4)
|
||||||
{
|
{
|
||||||
g_pixel_shader_cache->SetPSConstant4f(const_number, f1, f2, f3, f4);
|
g_pixel_shader_cache->SetPSConstant4f(const_number, f1, f2, f3, f4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetPSConstant4fv(unsigned int const_number, const float *f)
|
void SetPSConstant4fv(unsigned int const_number, const float *f)
|
||||||
{
|
{
|
||||||
g_pixel_shader_cache->SetPSConstant4fv(const_number, f);
|
g_pixel_shader_cache->SetPSConstant4fv(const_number, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetMultiPSConstant4fv(unsigned int const_number, unsigned int count, const float *f)
|
void SetMultiPSConstant4fv(unsigned int const_number, unsigned int count, const float *f)
|
||||||
{
|
{
|
||||||
g_pixel_shader_cache->SetMultiPSConstant4fv(const_number, count, f);
|
g_pixel_shader_cache->SetMultiPSConstant4fv(const_number, count, f);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
|
|
||||||
#ifndef _PIXELSHADERCACHE_H_
|
#ifndef _PIXELSHADERCACHE_H_
|
||||||
#define _PIXELSHADERCACHE_H_
|
#define _PIXELSHADERCACHE_H_
|
||||||
|
|
||||||
class PixelShaderCacheBase
|
class PixelShaderCacheBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~PixelShaderCacheBase() {}
|
virtual ~PixelShaderCacheBase() {}
|
||||||
|
|
||||||
virtual bool SetShader(bool dstAlphaEnable) = 0;
|
virtual bool SetShader(bool dstAlphaEnable) = 0;
|
||||||
|
|
||||||
virtual void SetPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4) = 0;
|
virtual void SetPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4) = 0;
|
||||||
virtual void SetPSConstant4fv(unsigned int const_number, const float *f) = 0;
|
virtual void SetPSConstant4fv(unsigned int const_number, const float *f) = 0;
|
||||||
virtual void SetMultiPSConstant4fv(unsigned int const_number, unsigned int count, const float *f) = 0;
|
virtual void SetMultiPSConstant4fv(unsigned int const_number, unsigned int count, const float *f) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,390 +1,390 @@
|
|||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
|
|
||||||
#include "Render.h"
|
#include "Render.h"
|
||||||
#include "BPMemory.h"
|
#include "BPMemory.h"
|
||||||
#include "Atomic.h"
|
#include "Atomic.h"
|
||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
#include "FramebufferManager.h"
|
#include "FramebufferManager.h"
|
||||||
|
|
||||||
#include "Fifo.h"
|
#include "Fifo.h"
|
||||||
#include "VertexShaderManager.h"
|
#include "VertexShaderManager.h"
|
||||||
#include "DLCache.h"
|
#include "DLCache.h"
|
||||||
#include "OnScreenDisplay.h"
|
#include "OnScreenDisplay.h"
|
||||||
#include "Statistics.h"
|
#include "Statistics.h"
|
||||||
|
|
||||||
#include "Renderer.h"
|
#include "Renderer.h"
|
||||||
|
|
||||||
#include "Main.h"
|
#include "Main.h"
|
||||||
|
|
||||||
int RendererBase::s_target_width;
|
int RendererBase::s_target_width;
|
||||||
int RendererBase::s_target_height;
|
int RendererBase::s_target_height;
|
||||||
|
|
||||||
int RendererBase::s_Fulltarget_width;
|
int RendererBase::s_Fulltarget_width;
|
||||||
int RendererBase::s_Fulltarget_height;
|
int RendererBase::s_Fulltarget_height;
|
||||||
|
|
||||||
int RendererBase::s_backbuffer_width;
|
int RendererBase::s_backbuffer_width;
|
||||||
int RendererBase::s_backbuffer_height;
|
int RendererBase::s_backbuffer_height;
|
||||||
|
|
||||||
int RendererBase::s_XFB_width;
|
int RendererBase::s_XFB_width;
|
||||||
int RendererBase::s_XFB_height;
|
int RendererBase::s_XFB_height;
|
||||||
|
|
||||||
float RendererBase::xScale;
|
float RendererBase::xScale;
|
||||||
float RendererBase::yScale;
|
float RendererBase::yScale;
|
||||||
|
|
||||||
int RendererBase::s_fps;
|
int RendererBase::s_fps;
|
||||||
|
|
||||||
u32 RendererBase::s_blendMode;
|
u32 RendererBase::s_blendMode;
|
||||||
bool RendererBase::XFBWrited;
|
bool RendererBase::XFBWrited;
|
||||||
|
|
||||||
float RendererBase::EFBxScale;
|
float RendererBase::EFBxScale;
|
||||||
float RendererBase::EFByScale;
|
float RendererBase::EFByScale;
|
||||||
|
|
||||||
volatile u32 RendererBase::s_swapRequested;
|
volatile u32 RendererBase::s_swapRequested;
|
||||||
|
|
||||||
//void VideoConfig::UpdateProjectionHack()
|
//void VideoConfig::UpdateProjectionHack()
|
||||||
//{
|
//{
|
||||||
// return;
|
// return;
|
||||||
// //::UpdateProjectionHack(g_Config.iPhackvalue);
|
// //::UpdateProjectionHack(g_Config.iPhackvalue);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
RendererBase::RendererBase()
|
RendererBase::RendererBase()
|
||||||
{
|
{
|
||||||
UpdateActiveConfig();
|
UpdateActiveConfig();
|
||||||
s_blendMode = 0;
|
s_blendMode = 0;
|
||||||
|
|
||||||
s_XFB_width = MAX_XFB_WIDTH;
|
s_XFB_width = MAX_XFB_WIDTH;
|
||||||
s_XFB_height = MAX_XFB_HEIGHT;
|
s_XFB_height = MAX_XFB_HEIGHT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// can maybe reuse this func in Renderer::Swap to eliminate redundant code
|
// can maybe reuse this func in Renderer::Swap to eliminate redundant code
|
||||||
void RendererBase::FramebufferSize(int w, int h)
|
void RendererBase::FramebufferSize(int w, int h)
|
||||||
{
|
{
|
||||||
TargetRectangle dst_rect;
|
TargetRectangle dst_rect;
|
||||||
ComputeDrawRectangle(w, h, false, &dst_rect);
|
ComputeDrawRectangle(w, h, false, &dst_rect);
|
||||||
|
|
||||||
xScale = (float)(dst_rect.right - dst_rect.left) / (float)s_XFB_width;
|
xScale = (float)(dst_rect.right - dst_rect.left) / (float)s_XFB_width;
|
||||||
yScale = (float)(dst_rect.bottom - dst_rect.top) / (float)s_XFB_height;
|
yScale = (float)(dst_rect.bottom - dst_rect.top) / (float)s_XFB_height;
|
||||||
|
|
||||||
// TODO: why these, prolly can remove them
|
// TODO: why these, prolly can remove them
|
||||||
const int s_LastAA = g_ActiveConfig.iMultisampleMode;
|
const int s_LastAA = g_ActiveConfig.iMultisampleMode;
|
||||||
const int s_LastEFBScale = g_ActiveConfig.iEFBScale;
|
const int s_LastEFBScale = g_ActiveConfig.iEFBScale;
|
||||||
|
|
||||||
switch (s_LastEFBScale)
|
switch (s_LastEFBScale)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
EFBxScale = xScale;
|
EFBxScale = xScale;
|
||||||
EFByScale = yScale;
|
EFByScale = yScale;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
EFBxScale = ceilf(xScale);
|
EFBxScale = ceilf(xScale);
|
||||||
EFByScale = ceilf(yScale);
|
EFByScale = ceilf(yScale);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
EFByScale = EFBxScale = (g_ActiveConfig.iEFBScale - 1);
|
EFByScale = EFBxScale = (g_ActiveConfig.iEFBScale - 1);
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
|
||||||
const float SupersampleCoeficient = s_LastAA + 1;
|
const float SupersampleCoeficient = s_LastAA + 1;
|
||||||
EFBxScale *= SupersampleCoeficient;
|
EFBxScale *= SupersampleCoeficient;
|
||||||
EFByScale *= SupersampleCoeficient;
|
EFByScale *= SupersampleCoeficient;
|
||||||
|
|
||||||
s_target_width = (int)(EFB_WIDTH * EFBxScale);
|
s_target_width = (int)(EFB_WIDTH * EFBxScale);
|
||||||
s_target_height = (int)(EFB_HEIGHT * EFByScale);
|
s_target_height = (int)(EFB_HEIGHT * EFByScale);
|
||||||
|
|
||||||
// TODO: set anything else?
|
// TODO: set anything else?
|
||||||
s_Fulltarget_width = s_target_width;
|
s_Fulltarget_width = s_target_width;
|
||||||
s_Fulltarget_height = s_target_height;
|
s_Fulltarget_height = s_target_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateViewport()
|
void UpdateViewport()
|
||||||
{
|
{
|
||||||
g_renderer->UpdateViewport();
|
g_renderer->UpdateViewport();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
|
void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
|
||||||
{
|
{
|
||||||
RendererBase::RenderToXFB(xfbAddr, fbWidth, fbHeight, sourceRc);
|
RendererBase::RenderToXFB(xfbAddr, fbWidth, fbHeight, sourceRc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// whats this for?
|
// whats this for?
|
||||||
bool IsD3D()
|
bool IsD3D()
|
||||||
{
|
{
|
||||||
//PanicAlert("IsD3D!");
|
//PanicAlert("IsD3D!");
|
||||||
// TODO: temporary
|
// TODO: temporary
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::RenderText(const char *pstr, int left, int top, u32 color)
|
void Renderer::RenderText(const char *pstr, int left, int top, u32 color)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererBase::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
|
void RendererBase::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
|
||||||
{
|
{
|
||||||
if (!fbWidth || !fbHeight)
|
if (!fbWidth || !fbHeight)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
VideoFifo_CheckEFBAccess();
|
VideoFifo_CheckEFBAccess();
|
||||||
VideoFifo_CheckSwapRequestAt(xfbAddr, fbWidth, fbHeight);
|
VideoFifo_CheckSwapRequestAt(xfbAddr, fbWidth, fbHeight);
|
||||||
XFBWrited = true;
|
XFBWrited = true;
|
||||||
|
|
||||||
// XXX: Without the VI, how would we know what kind of field this is? So
|
// XXX: Without the VI, how would we know what kind of field this is? So
|
||||||
// just use progressive.
|
// just use progressive.
|
||||||
|
|
||||||
if (g_ActiveConfig.bUseXFB)
|
if (g_ActiveConfig.bUseXFB)
|
||||||
{
|
{
|
||||||
g_framebuffer_manager->CopyToXFB(xfbAddr, fbWidth, fbHeight, sourceRc);
|
g_framebuffer_manager->CopyToXFB(xfbAddr, fbWidth, fbHeight, sourceRc);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_renderer->Swap(xfbAddr, FIELD_PROGRESSIVE, fbWidth, fbHeight, sourceRc);
|
g_renderer->Swap(xfbAddr, FIELD_PROGRESSIVE, fbWidth, fbHeight, sourceRc);
|
||||||
Common::AtomicStoreRelease(s_swapRequested, FALSE);
|
Common::AtomicStoreRelease(s_swapRequested, FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TargetRectangle RendererBase::ConvertEFBRectangle(const EFBRectangle& rc)
|
TargetRectangle RendererBase::ConvertEFBRectangle(const EFBRectangle& rc)
|
||||||
{
|
{
|
||||||
int Xstride = (s_Fulltarget_width - s_target_width) / 2;
|
int Xstride = (s_Fulltarget_width - s_target_width) / 2;
|
||||||
int Ystride = (s_Fulltarget_height - s_target_height) / 2;
|
int Ystride = (s_Fulltarget_height - s_target_height) / 2;
|
||||||
TargetRectangle result;
|
TargetRectangle result;
|
||||||
result.left = (int)(rc.left * EFBxScale) + Xstride;
|
result.left = (int)(rc.left * EFBxScale) + Xstride;
|
||||||
result.top = (int)(rc.top * EFByScale) + Ystride;
|
result.top = (int)(rc.top * EFByScale) + Ystride;
|
||||||
result.right = (int)(rc.right * EFBxScale) + Xstride;
|
result.right = (int)(rc.right * EFBxScale) + Xstride;
|
||||||
result.bottom = (int)(rc.bottom * EFByScale) + Ystride;
|
result.bottom = (int)(rc.bottom * EFByScale) + Ystride;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RendererBase::SetScissorRect(EFBRectangle &rc)
|
bool RendererBase::SetScissorRect(EFBRectangle &rc)
|
||||||
{
|
{
|
||||||
int xoff = bpmem.scissorOffset.x * 2 - 342;
|
int xoff = bpmem.scissorOffset.x * 2 - 342;
|
||||||
int yoff = bpmem.scissorOffset.y * 2 - 342;
|
int yoff = bpmem.scissorOffset.y * 2 - 342;
|
||||||
|
|
||||||
rc.left = bpmem.scissorTL.x - xoff - 342;
|
rc.left = bpmem.scissorTL.x - xoff - 342;
|
||||||
rc.top = bpmem.scissorTL.y - yoff - 342;
|
rc.top = bpmem.scissorTL.y - yoff - 342;
|
||||||
rc.right = bpmem.scissorBR.x - xoff - 341;
|
rc.right = bpmem.scissorBR.x - xoff - 341;
|
||||||
rc.bottom = bpmem.scissorBR.y - yoff - 341;
|
rc.bottom = bpmem.scissorBR.y - yoff - 341;
|
||||||
|
|
||||||
int Xstride = (s_Fulltarget_width - s_target_width) / 2;
|
int Xstride = (s_Fulltarget_width - s_target_width) / 2;
|
||||||
int Ystride = (s_Fulltarget_height - s_target_height) / 2;
|
int Ystride = (s_Fulltarget_height - s_target_height) / 2;
|
||||||
|
|
||||||
rc.left = (int)(rc.left * EFBxScale);
|
rc.left = (int)(rc.left * EFBxScale);
|
||||||
rc.top = (int)(rc.top * EFByScale);
|
rc.top = (int)(rc.top * EFByScale);
|
||||||
rc.right = (int)(rc.right * EFBxScale);
|
rc.right = (int)(rc.right * EFBxScale);
|
||||||
rc.bottom = (int)(rc.bottom * EFByScale);
|
rc.bottom = (int)(rc.bottom * EFByScale);
|
||||||
|
|
||||||
if (rc.left < 0) rc.left = 0;
|
if (rc.left < 0) rc.left = 0;
|
||||||
if (rc.right < 0) rc.right = 0;
|
if (rc.right < 0) rc.right = 0;
|
||||||
if (rc.left > s_target_width) rc.left = s_target_width;
|
if (rc.left > s_target_width) rc.left = s_target_width;
|
||||||
if (rc.right > s_target_width) rc.right = s_target_width;
|
if (rc.right > s_target_width) rc.right = s_target_width;
|
||||||
if (rc.top < 0) rc.top = 0;
|
if (rc.top < 0) rc.top = 0;
|
||||||
if (rc.bottom < 0) rc.bottom = 0;
|
if (rc.bottom < 0) rc.bottom = 0;
|
||||||
if (rc.top > s_target_height) rc.top = s_target_height;
|
if (rc.top > s_target_height) rc.top = s_target_height;
|
||||||
if (rc.bottom > s_target_height) rc.bottom = s_target_height;
|
if (rc.bottom > s_target_height) rc.bottom = s_target_height;
|
||||||
|
|
||||||
rc.left += Xstride;
|
rc.left += Xstride;
|
||||||
rc.top += Ystride;
|
rc.top += Ystride;
|
||||||
rc.right += Xstride;
|
rc.right += Xstride;
|
||||||
rc.bottom += Ystride;
|
rc.bottom += Ystride;
|
||||||
|
|
||||||
if (rc.left > rc.right)
|
if (rc.left > rc.right)
|
||||||
{
|
{
|
||||||
int temp = rc.right;
|
int temp = rc.right;
|
||||||
rc.right = rc.left;
|
rc.right = rc.left;
|
||||||
rc.left = temp;
|
rc.left = temp;
|
||||||
}
|
}
|
||||||
if (rc.top > rc.bottom)
|
if (rc.top > rc.bottom)
|
||||||
{
|
{
|
||||||
int temp = rc.bottom;
|
int temp = rc.bottom;
|
||||||
rc.bottom = rc.top;
|
rc.bottom = rc.top;
|
||||||
rc.top = temp;
|
rc.top = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (rc.right >= rc.left && rc.bottom >= rc.top);
|
return (rc.right >= rc.left && rc.bottom >= rc.top);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererBase::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight, const EFBRectangle& rc)
|
void RendererBase::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight, const EFBRectangle& rc)
|
||||||
{
|
{
|
||||||
if (g_bSkipCurrentFrame || (!XFBWrited && !g_ActiveConfig.bUseRealXFB) || !fbWidth || !fbHeight)
|
if (g_bSkipCurrentFrame || (!XFBWrited && !g_ActiveConfig.bUseRealXFB) || !fbWidth || !fbHeight)
|
||||||
{
|
{
|
||||||
g_VideoInitialize.pCopiedToXFB(false);
|
g_VideoInitialize.pCopiedToXFB(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// this function is called after the XFB field is changed, not after
|
// this function is called after the XFB field is changed, not after
|
||||||
// EFB is copied to XFB. In this way, flickering is reduced in games
|
// EFB is copied to XFB. In this way, flickering is reduced in games
|
||||||
// and seems to also give more FPS in ZTP
|
// and seems to also give more FPS in ZTP
|
||||||
|
|
||||||
if (field == FIELD_LOWER)
|
if (field == FIELD_LOWER)
|
||||||
xfbAddr -= fbWidth * 2;
|
xfbAddr -= fbWidth * 2;
|
||||||
u32 xfbCount = 0;
|
u32 xfbCount = 0;
|
||||||
const XFBSourceBase** xfbSourceList = g_framebuffer_manager->GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
|
const XFBSourceBase** xfbSourceList = g_framebuffer_manager->GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
|
||||||
|
|
||||||
if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB)
|
if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB)
|
||||||
{
|
{
|
||||||
g_VideoInitialize.pCopiedToXFB(false);
|
g_VideoInitialize.pCopiedToXFB(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_renderer->ResetAPIState();
|
g_renderer->ResetAPIState();
|
||||||
|
|
||||||
// prepare copying the XFBs to our backbuffer
|
// prepare copying the XFBs to our backbuffer
|
||||||
TargetRectangle dst_rect;
|
TargetRectangle dst_rect;
|
||||||
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect);
|
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect);
|
||||||
|
|
||||||
g_renderer->PrepareXFBCopy(dst_rect);
|
g_renderer->PrepareXFBCopy(dst_rect);
|
||||||
|
|
||||||
if (g_ActiveConfig.bUseXFB)
|
if (g_ActiveConfig.bUseXFB)
|
||||||
{
|
{
|
||||||
const XFBSourceBase* xfbSource;
|
const XFBSourceBase* xfbSource;
|
||||||
|
|
||||||
// draw each xfb source
|
// draw each xfb source
|
||||||
for (u32 i = 0; i < xfbCount; ++i)
|
for (u32 i = 0; i < xfbCount; ++i)
|
||||||
{
|
{
|
||||||
xfbSource = xfbSourceList[i];
|
xfbSource = xfbSourceList[i];
|
||||||
TargetRectangle sourceRc;
|
TargetRectangle sourceRc;
|
||||||
|
|
||||||
//if (g_ActiveConfig.bAutoScale)
|
//if (g_ActiveConfig.bAutoScale)
|
||||||
//{
|
//{
|
||||||
// sourceRc = xfbSource->sourceRc;
|
// sourceRc = xfbSource->sourceRc;
|
||||||
//}
|
//}
|
||||||
//else
|
//else
|
||||||
//{
|
//{
|
||||||
sourceRc.left = 0;
|
sourceRc.left = 0;
|
||||||
sourceRc.top = 0;
|
sourceRc.top = 0;
|
||||||
sourceRc.right = xfbSource->texWidth;
|
sourceRc.right = xfbSource->texWidth;
|
||||||
sourceRc.bottom = xfbSource->texHeight;
|
sourceRc.bottom = xfbSource->texHeight;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
MathUtil::Rectangle<float> drawRc;
|
MathUtil::Rectangle<float> drawRc;
|
||||||
|
|
||||||
if (g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB)
|
if (g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB)
|
||||||
{
|
{
|
||||||
// use virtual xfb with offset
|
// use virtual xfb with offset
|
||||||
int xfbHeight = xfbSource->srcHeight;
|
int xfbHeight = xfbSource->srcHeight;
|
||||||
int xfbWidth = xfbSource->srcWidth;
|
int xfbWidth = xfbSource->srcWidth;
|
||||||
int hOffset = ((s32)xfbSource->srcAddr - (s32)xfbAddr) / ((s32)fbWidth * 2);
|
int hOffset = ((s32)xfbSource->srcAddr - (s32)xfbAddr) / ((s32)fbWidth * 2);
|
||||||
|
|
||||||
drawRc.bottom = 1.0f - 2.0f * ((hOffset) / (float)fbHeight);
|
drawRc.bottom = 1.0f - 2.0f * ((hOffset) / (float)fbHeight);
|
||||||
drawRc.top = 1.0f - 2.0f * ((hOffset + xfbHeight) / (float)fbHeight);
|
drawRc.top = 1.0f - 2.0f * ((hOffset + xfbHeight) / (float)fbHeight);
|
||||||
drawRc.left = -(xfbWidth / (float)fbWidth);
|
drawRc.left = -(xfbWidth / (float)fbWidth);
|
||||||
drawRc.right = (xfbWidth / (float)fbWidth);
|
drawRc.right = (xfbWidth / (float)fbWidth);
|
||||||
|
|
||||||
if (!g_ActiveConfig.bAutoScale)
|
if (!g_ActiveConfig.bAutoScale)
|
||||||
{
|
{
|
||||||
// scale draw area for a 1 to 1 pixel mapping with the draw target
|
// scale draw area for a 1 to 1 pixel mapping with the draw target
|
||||||
float vScale = (float)fbHeight / (float)s_backbuffer_height;
|
float vScale = (float)fbHeight / (float)s_backbuffer_height;
|
||||||
float hScale = (float)fbWidth / (float)s_backbuffer_width;
|
float hScale = (float)fbWidth / (float)s_backbuffer_width;
|
||||||
|
|
||||||
drawRc.top *= vScale;
|
drawRc.top *= vScale;
|
||||||
drawRc.bottom *= vScale;
|
drawRc.bottom *= vScale;
|
||||||
drawRc.left *= hScale;
|
drawRc.left *= hScale;
|
||||||
drawRc.right *= hScale;
|
drawRc.right *= hScale;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
drawRc.top = -1;
|
drawRc.top = -1;
|
||||||
drawRc.bottom = 1;
|
drawRc.bottom = 1;
|
||||||
drawRc.left = -1;
|
drawRc.left = -1;
|
||||||
drawRc.right = 1;
|
drawRc.right = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_renderer->Draw(xfbSource, sourceRc, drawRc, rc);
|
g_renderer->Draw(xfbSource, sourceRc, drawRc, rc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// TODO: organize drawRc stuff
|
// TODO: organize drawRc stuff
|
||||||
MathUtil::Rectangle<float> drawRc;
|
MathUtil::Rectangle<float> drawRc;
|
||||||
drawRc.top = -1;
|
drawRc.top = -1;
|
||||||
drawRc.bottom = 1;
|
drawRc.bottom = 1;
|
||||||
drawRc.left = -1;
|
drawRc.left = -1;
|
||||||
drawRc.right = 1;
|
drawRc.right = 1;
|
||||||
|
|
||||||
const TargetRectangle targetRc = ConvertEFBRectangle(rc);
|
const TargetRectangle targetRc = ConvertEFBRectangle(rc);
|
||||||
g_renderer->Draw(NULL, targetRc, drawRc, rc);
|
g_renderer->Draw(NULL, targetRc, drawRc, rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// done with drawing the game stuff, good moment to save a screenshot
|
// done with drawing the game stuff, good moment to save a screenshot
|
||||||
// TODO: screenshot code
|
// TODO: screenshot code
|
||||||
//
|
//
|
||||||
|
|
||||||
// finally present some information
|
// finally present some information
|
||||||
// TODO: debug text, fps, etc...
|
// TODO: debug text, fps, etc...
|
||||||
//
|
//
|
||||||
|
|
||||||
OSD::DrawMessages();
|
OSD::DrawMessages();
|
||||||
|
|
||||||
g_renderer->EndFrame();
|
g_renderer->EndFrame();
|
||||||
|
|
||||||
++frameCount;
|
++frameCount;
|
||||||
|
|
||||||
DLCache::ProgressiveCleanup();
|
DLCache::ProgressiveCleanup();
|
||||||
g_texture_cache->Cleanup();
|
g_texture_cache->Cleanup();
|
||||||
|
|
||||||
// check for configuration changes
|
// check for configuration changes
|
||||||
const int last_efbscale = g_ActiveConfig.iEFBScale;
|
const int last_efbscale = g_ActiveConfig.iEFBScale;
|
||||||
//const int last_aa = g_ActiveConfig.iMultisampleMode;
|
//const int last_aa = g_ActiveConfig.iMultisampleMode;
|
||||||
|
|
||||||
UpdateActiveConfig();
|
UpdateActiveConfig();
|
||||||
|
|
||||||
|
|
||||||
bool window_resized = g_renderer->CheckForResize();
|
bool window_resized = g_renderer->CheckForResize();
|
||||||
|
|
||||||
bool xfbchanged = false;
|
bool xfbchanged = false;
|
||||||
if (s_XFB_width != fbWidth || s_XFB_height != fbHeight)
|
if (s_XFB_width != fbWidth || s_XFB_height != fbHeight)
|
||||||
{
|
{
|
||||||
xfbchanged = true;
|
xfbchanged = true;
|
||||||
s_XFB_width = fbWidth;
|
s_XFB_width = fbWidth;
|
||||||
s_XFB_height = fbHeight;
|
s_XFB_height = fbHeight;
|
||||||
if (s_XFB_width < 1) s_XFB_width = MAX_XFB_WIDTH;
|
if (s_XFB_width < 1) s_XFB_width = MAX_XFB_WIDTH;
|
||||||
if (s_XFB_width > MAX_XFB_WIDTH) s_XFB_width = MAX_XFB_WIDTH;
|
if (s_XFB_width > MAX_XFB_WIDTH) s_XFB_width = MAX_XFB_WIDTH;
|
||||||
if (s_XFB_height < 1) s_XFB_height = MAX_XFB_HEIGHT;
|
if (s_XFB_height < 1) s_XFB_height = MAX_XFB_HEIGHT;
|
||||||
if (s_XFB_height > MAX_XFB_HEIGHT) s_XFB_height = MAX_XFB_HEIGHT;
|
if (s_XFB_height > MAX_XFB_HEIGHT) s_XFB_height = MAX_XFB_HEIGHT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// update FPS counter
|
// update FPS counter
|
||||||
// TODO: make this better
|
// TODO: make this better
|
||||||
static int fpscount = 0;
|
static int fpscount = 0;
|
||||||
static unsigned long lasttime = 0;
|
static unsigned long lasttime = 0;
|
||||||
if (Common::Timer::GetTimeMs() - lasttime >= 1000)
|
if (Common::Timer::GetTimeMs() - lasttime >= 1000)
|
||||||
{
|
{
|
||||||
lasttime = Common::Timer::GetTimeMs();
|
lasttime = Common::Timer::GetTimeMs();
|
||||||
s_fps = fpscount;
|
s_fps = fpscount;
|
||||||
fpscount = 0;
|
fpscount = 0;
|
||||||
}
|
}
|
||||||
if (XFBWrited)
|
if (XFBWrited)
|
||||||
++fpscount;
|
++fpscount;
|
||||||
|
|
||||||
// set default viewport and scissor, for the clear to work correctly
|
// set default viewport and scissor, for the clear to work correctly
|
||||||
stats.ResetFrame();
|
stats.ResetFrame();
|
||||||
|
|
||||||
// done. Show our work ;)
|
// done. Show our work ;)
|
||||||
g_renderer->Present();
|
g_renderer->Present();
|
||||||
|
|
||||||
// resize the back buffers NOW to avoid flickering when resizing windows
|
// resize the back buffers NOW to avoid flickering when resizing windows
|
||||||
if (xfbchanged || window_resized || last_efbscale != g_ActiveConfig.iEFBScale)
|
if (xfbchanged || window_resized || last_efbscale != g_ActiveConfig.iEFBScale)
|
||||||
{
|
{
|
||||||
g_renderer->GetBackBufferSize(&s_backbuffer_width, &s_backbuffer_height);
|
g_renderer->GetBackBufferSize(&s_backbuffer_width, &s_backbuffer_height);
|
||||||
|
|
||||||
FramebufferSize(s_backbuffer_width, s_backbuffer_height);
|
FramebufferSize(s_backbuffer_width, s_backbuffer_height);
|
||||||
|
|
||||||
g_renderer->RecreateFramebufferManger();
|
g_renderer->RecreateFramebufferManger();
|
||||||
}
|
}
|
||||||
|
|
||||||
// begin next frame
|
// begin next frame
|
||||||
g_renderer->RestoreAPIState();
|
g_renderer->RestoreAPIState();
|
||||||
|
|
||||||
g_renderer->BeginFrame();
|
g_renderer->BeginFrame();
|
||||||
|
|
||||||
g_renderer->UpdateViewport();
|
g_renderer->UpdateViewport();
|
||||||
VertexShaderManager::SetViewportChanged();
|
VertexShaderManager::SetViewportChanged();
|
||||||
g_VideoInitialize.pCopiedToXFB(XFBWrited || g_ActiveConfig.bUseRealXFB);
|
g_VideoInitialize.pCopiedToXFB(XFBWrited || g_ActiveConfig.bUseRealXFB);
|
||||||
XFBWrited = false;
|
XFBWrited = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,99 +1,99 @@
|
|||||||
|
|
||||||
#ifndef _RENDER_H_
|
#ifndef _RENDER_H_
|
||||||
#define _RENDER_H_
|
#define _RENDER_H_
|
||||||
|
|
||||||
#include "VideoCommon.h"
|
#include "VideoCommon.h"
|
||||||
#include "CommonTypes.h"
|
#include "CommonTypes.h"
|
||||||
#include "FramebufferManager.h"
|
#include "FramebufferManager.h"
|
||||||
|
|
||||||
class RendererBase
|
class RendererBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RendererBase();
|
RendererBase();
|
||||||
virtual ~RendererBase() {}
|
virtual ~RendererBase() {}
|
||||||
|
|
||||||
static void FramebufferSize(int w, int h);
|
static void FramebufferSize(int w, int h);
|
||||||
|
|
||||||
static void RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc);
|
static void RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc);
|
||||||
|
|
||||||
virtual u32 AccessEFB(EFBAccessType type, int x, int y) = 0;
|
virtual u32 AccessEFB(EFBAccessType type, int x, int y) = 0;
|
||||||
|
|
||||||
static void Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc);
|
static void Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc);
|
||||||
|
|
||||||
// virtual funcs used in Swap()
|
// virtual funcs used in Swap()
|
||||||
virtual void PrepareXFBCopy(const TargetRectangle &dst_rect) = 0;
|
virtual void PrepareXFBCopy(const TargetRectangle &dst_rect) = 0;
|
||||||
virtual void Draw(const XFBSourceBase* xfbSource, const TargetRectangle& sourceRc,
|
virtual void Draw(const XFBSourceBase* xfbSource, const TargetRectangle& sourceRc,
|
||||||
const MathUtil::Rectangle<float>& drawRc, const EFBRectangle& rc) = 0;
|
const MathUtil::Rectangle<float>& drawRc, const EFBRectangle& rc) = 0;
|
||||||
virtual void EndFrame() = 0;
|
virtual void EndFrame() = 0;
|
||||||
virtual void Present() = 0;
|
virtual void Present() = 0;
|
||||||
virtual bool CheckForResize() = 0;
|
virtual bool CheckForResize() = 0;
|
||||||
virtual void GetBackBufferSize(int* w, int* h) = 0;
|
virtual void GetBackBufferSize(int* w, int* h) = 0;
|
||||||
virtual void RecreateFramebufferManger() = 0;
|
virtual void RecreateFramebufferManger() = 0;
|
||||||
virtual void BeginFrame() = 0;
|
virtual void BeginFrame() = 0;
|
||||||
|
|
||||||
// hmm
|
// hmm
|
||||||
virtual bool SetScissorRect() = 0;
|
virtual bool SetScissorRect() = 0;
|
||||||
static bool SetScissorRect(EFBRectangle &rc);
|
static bool SetScissorRect(EFBRectangle &rc);
|
||||||
|
|
||||||
static TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc);
|
static TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc);
|
||||||
|
|
||||||
virtual void UpdateViewport() = 0;
|
virtual void UpdateViewport() = 0;
|
||||||
virtual void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z) = 0;
|
virtual void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z) = 0;
|
||||||
|
|
||||||
virtual void ResetAPIState() = 0;
|
virtual void ResetAPIState() = 0;
|
||||||
virtual void RestoreAPIState() = 0;
|
virtual void RestoreAPIState() = 0;
|
||||||
|
|
||||||
static int GetTargetWidth() { return s_target_width; }
|
static int GetTargetWidth() { return s_target_width; }
|
||||||
static int GetTargetHeight() { return s_target_height; }
|
static int GetTargetHeight() { return s_target_height; }
|
||||||
static int GetFullTargetWidth() { return s_Fulltarget_width; }
|
static int GetFullTargetWidth() { return s_Fulltarget_width; }
|
||||||
static int GetFullTargetHeight() { return s_Fulltarget_height; }
|
static int GetFullTargetHeight() { return s_Fulltarget_height; }
|
||||||
static float GetTargetScaleX() { return EFBxScale; }
|
static float GetTargetScaleX() { return EFBxScale; }
|
||||||
static float GetTargetScaleY() { return EFByScale; }
|
static float GetTargetScaleY() { return EFByScale; }
|
||||||
static int GetFrameBufferWidth() { return s_backbuffer_width; }
|
static int GetFrameBufferWidth() { return s_backbuffer_width; }
|
||||||
static int GetFrameBufferHeight() { return s_backbuffer_height; }
|
static int GetFrameBufferHeight() { return s_backbuffer_height; }
|
||||||
static float GetXFBScaleX() { return xScale; }
|
static float GetXFBScaleX() { return xScale; }
|
||||||
static float GetXFBScaleY() { return yScale; }
|
static float GetXFBScaleY() { return yScale; }
|
||||||
|
|
||||||
virtual void SetColorMask() {}
|
virtual void SetColorMask() {}
|
||||||
virtual void SetBlendMode(bool forceUpdate) {}
|
virtual void SetBlendMode(bool forceUpdate) {}
|
||||||
virtual void SetSamplerState(int stage, int texindex) {}
|
virtual void SetSamplerState(int stage, int texindex) {}
|
||||||
virtual void SetDitherMode() {}
|
virtual void SetDitherMode() {}
|
||||||
virtual void SetLineWidth() {}
|
virtual void SetLineWidth() {}
|
||||||
virtual void SetInterlacingMode() {}
|
virtual void SetInterlacingMode() {}
|
||||||
virtual void SetGenerationMode() = 0;
|
virtual void SetGenerationMode() = 0;
|
||||||
virtual void SetDepthMode() = 0;
|
virtual void SetDepthMode() = 0;
|
||||||
virtual void SetLogicOpMode() = 0;
|
virtual void SetLogicOpMode() = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// TODO: are all of these needed?
|
// TODO: are all of these needed?
|
||||||
static int s_target_width;
|
static int s_target_width;
|
||||||
static int s_target_height;
|
static int s_target_height;
|
||||||
|
|
||||||
static int s_Fulltarget_width;
|
static int s_Fulltarget_width;
|
||||||
static int s_Fulltarget_height;
|
static int s_Fulltarget_height;
|
||||||
|
|
||||||
static int s_backbuffer_width;
|
static int s_backbuffer_width;
|
||||||
static int s_backbuffer_height;
|
static int s_backbuffer_height;
|
||||||
//
|
//
|
||||||
|
|
||||||
static int s_fps;
|
static int s_fps;
|
||||||
|
|
||||||
static u32 s_blendMode;
|
static u32 s_blendMode;
|
||||||
static bool XFBWrited;
|
static bool XFBWrited;
|
||||||
|
|
||||||
// these go with the settings in the GUI 1x,2x,3x,etc
|
// these go with the settings in the GUI 1x,2x,3x,etc
|
||||||
static float EFBxScale;
|
static float EFBxScale;
|
||||||
static float EFByScale;
|
static float EFByScale;
|
||||||
// these seem be the fractional value
|
// these seem be the fractional value
|
||||||
// TODO: are these ones needed?
|
// TODO: are these ones needed?
|
||||||
static float xScale;
|
static float xScale;
|
||||||
static float yScale;
|
static float yScale;
|
||||||
|
|
||||||
static int s_XFB_width;
|
static int s_XFB_width;
|
||||||
static int s_XFB_height;
|
static int s_XFB_height;
|
||||||
|
|
||||||
static volatile u32 s_swapRequested;
|
static volatile u32 s_swapRequested;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,80 +1,80 @@
|
|||||||
|
|
||||||
#ifndef _TEXTURECACHE_H_
|
#ifndef _TEXTURECACHE_H_
|
||||||
#define _TEXTURECACHE_H_
|
#define _TEXTURECACHE_H_
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include "CommonTypes.h"
|
#include "CommonTypes.h"
|
||||||
#include "VideoCommon.h"
|
#include "VideoCommon.h"
|
||||||
#include "TextureDecoder.h"
|
#include "TextureDecoder.h"
|
||||||
|
|
||||||
unsigned int GetPow2(unsigned int val);
|
unsigned int GetPow2(unsigned int val);
|
||||||
|
|
||||||
class TextureCacheBase
|
class TextureCacheBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
struct TCacheEntryBase
|
struct TCacheEntryBase
|
||||||
{
|
{
|
||||||
u32 addr;
|
u32 addr;
|
||||||
u32 size_in_bytes;
|
u32 size_in_bytes;
|
||||||
u64 hash;
|
u64 hash;
|
||||||
u32 paletteHash;
|
u32 paletteHash;
|
||||||
u32 oldpixel;
|
u32 oldpixel;
|
||||||
|
|
||||||
int frameCount;
|
int frameCount;
|
||||||
unsigned int w, h, fmt, MipLevels;
|
unsigned int w, h, fmt, MipLevels;
|
||||||
int Scaledw, Scaledh;
|
int Scaledw, Scaledh;
|
||||||
|
|
||||||
bool isRenderTarget;
|
bool isRenderTarget;
|
||||||
bool isNonPow2;
|
bool isNonPow2;
|
||||||
|
|
||||||
TCacheEntryBase() : addr(0), size_in_bytes(0), hash(0), paletteHash(0), oldpixel(0),
|
TCacheEntryBase() : addr(0), size_in_bytes(0), hash(0), paletteHash(0), oldpixel(0),
|
||||||
frameCount(0), w(0), h(0), fmt(0), MipLevels(0), Scaledw(0), Scaledh(0),
|
frameCount(0), w(0), h(0), fmt(0), MipLevels(0), Scaledw(0), Scaledh(0),
|
||||||
isRenderTarget(false), isNonPow2(true) {}
|
isRenderTarget(false), isNonPow2(true) {}
|
||||||
|
|
||||||
virtual ~TCacheEntryBase();
|
virtual ~TCacheEntryBase();
|
||||||
|
|
||||||
virtual void Load(unsigned int width, unsigned int height,
|
virtual void Load(unsigned int width, unsigned int height,
|
||||||
unsigned int expanded_width, unsigned int levels) = 0;
|
unsigned int expanded_width, unsigned int levels) = 0;
|
||||||
|
|
||||||
virtual void FromRenderTarget(bool bFromZBuffer, bool bScaleByHalf,
|
virtual void FromRenderTarget(bool bFromZBuffer, bool bScaleByHalf,
|
||||||
unsigned int cbufid, const float colmat[], const EFBRectangle &source_rect) = 0;
|
unsigned int cbufid, const float colmat[], const EFBRectangle &source_rect) = 0;
|
||||||
|
|
||||||
virtual void Bind(unsigned int stage) = 0;
|
virtual void Bind(unsigned int stage) = 0;
|
||||||
|
|
||||||
bool IntersectsMemoryRange(u32 range_address, u32 range_size) const;
|
bool IntersectsMemoryRange(u32 range_address, u32 range_size) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
friend struct TCacheEntryBase;
|
friend struct TCacheEntryBase;
|
||||||
|
|
||||||
TextureCacheBase();
|
TextureCacheBase();
|
||||||
virtual ~TextureCacheBase();
|
virtual ~TextureCacheBase();
|
||||||
|
|
||||||
static void Cleanup();
|
static void Cleanup();
|
||||||
|
|
||||||
static void Invalidate(bool shutdown);
|
static void Invalidate(bool shutdown);
|
||||||
static void InvalidateRange(u32 start_address, u32 size);
|
static void InvalidateRange(u32 start_address, u32 size);
|
||||||
|
|
||||||
// TODO: make these 2 static?
|
// TODO: make these 2 static?
|
||||||
TCacheEntryBase* Load(unsigned int stage, u32 address, unsigned int width,
|
TCacheEntryBase* Load(unsigned int stage, u32 address, unsigned int width,
|
||||||
unsigned int height, unsigned int tex_format, unsigned int tlutaddr,
|
unsigned int height, unsigned int tex_format, unsigned int tlutaddr,
|
||||||
unsigned int tlutfmt, bool UseNativeMips, unsigned int maxlevel);
|
unsigned int tlutfmt, bool UseNativeMips, unsigned int maxlevel);
|
||||||
|
|
||||||
void CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool bIsIntensityFmt,
|
void CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool bIsIntensityFmt,
|
||||||
u32 copyfmt, bool bScaleByHalf, const EFBRectangle &source_rect);
|
u32 copyfmt, bool bScaleByHalf, const EFBRectangle &source_rect);
|
||||||
|
|
||||||
virtual TCacheEntryBase* CreateTexture(unsigned int width, unsigned int height,
|
virtual TCacheEntryBase* CreateTexture(unsigned int width, unsigned int height,
|
||||||
unsigned int expanded_width, unsigned int tex_levels, PC_TexFormat pcfmt) = 0;
|
unsigned int expanded_width, unsigned int tex_levels, PC_TexFormat pcfmt) = 0;
|
||||||
|
|
||||||
virtual TCacheEntryBase* CreateRenderTargetTexture(int scaled_tex_w, int scaled_tex_h) = 0;
|
virtual TCacheEntryBase* CreateRenderTargetTexture(int scaled_tex_w, int scaled_tex_h) = 0;
|
||||||
|
|
||||||
static void ClearRenderTargets();
|
static void ClearRenderTargets();
|
||||||
static void MakeRangeDynamic(u32 start_address, u32 size);
|
static void MakeRangeDynamic(u32 start_address, u32 size);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typedef std::map<u32, TCacheEntryBase*> TexCache;
|
typedef std::map<u32, TCacheEntryBase*> TexCache;
|
||||||
static TexCache textures;
|
static TexCache textures;
|
||||||
static u8 *temp;
|
static u8 *temp;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,268 +1,268 @@
|
|||||||
|
|
||||||
// VideoCommon
|
// VideoCommon
|
||||||
|
|
||||||
#include "CommonTypes.h"
|
#include "CommonTypes.h"
|
||||||
|
|
||||||
#include "OpcodeDecoding.h"
|
#include "OpcodeDecoding.h"
|
||||||
#include "IndexGenerator.h"
|
#include "IndexGenerator.h"
|
||||||
#include "Statistics.h"
|
#include "Statistics.h"
|
||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
#include "PixelShaderManager.h"
|
#include "PixelShaderManager.h"
|
||||||
#include "NativeVertexFormat.h"
|
#include "NativeVertexFormat.h"
|
||||||
#include "VertexShaderManager.h"
|
#include "VertexShaderManager.h"
|
||||||
#include "Profiler.h"
|
#include "Profiler.h"
|
||||||
|
|
||||||
//
|
//
|
||||||
#include "TextureCache.h"
|
#include "TextureCache.h"
|
||||||
#include "VertexManager.h"
|
#include "VertexManager.h"
|
||||||
#include "Main.h"
|
#include "Main.h"
|
||||||
|
|
||||||
u16* VertexManagerBase::TIBuffer;
|
u16* VertexManagerBase::TIBuffer;
|
||||||
u16* VertexManagerBase::LIBuffer;
|
u16* VertexManagerBase::LIBuffer;
|
||||||
u16* VertexManagerBase::PIBuffer;
|
u16* VertexManagerBase::PIBuffer;
|
||||||
bool VertexManagerBase::Flushed;
|
bool VertexManagerBase::Flushed;
|
||||||
|
|
||||||
int VertexManagerBase::lastPrimitive;
|
int VertexManagerBase::lastPrimitive;
|
||||||
u8* VertexManagerBase::LocalVBuffer;
|
u8* VertexManagerBase::LocalVBuffer;
|
||||||
|
|
||||||
// TODO: put this in .h perhaps
|
// TODO: put this in .h perhaps
|
||||||
extern NativeVertexFormat* g_nativeVertexFmt;
|
extern NativeVertexFormat* g_nativeVertexFmt;
|
||||||
|
|
||||||
NativeVertexFormat* NativeVertexFormat::Create()
|
NativeVertexFormat* NativeVertexFormat::Create()
|
||||||
{
|
{
|
||||||
return g_vertex_manager->CreateNativeVertexFormat();
|
return g_vertex_manager->CreateNativeVertexFormat();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexManagerBase::ResetBuffer()
|
void VertexManagerBase::ResetBuffer()
|
||||||
{
|
{
|
||||||
s_pCurBufferPointer = LocalVBuffer;
|
s_pCurBufferPointer = LocalVBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
VertexManagerBase::VertexManagerBase()
|
VertexManagerBase::VertexManagerBase()
|
||||||
{
|
{
|
||||||
LocalVBuffer = new u8[MAXVBUFFERSIZE];
|
LocalVBuffer = new u8[MAXVBUFFERSIZE];
|
||||||
TIBuffer = new u16[MAXIBUFFERSIZE];
|
TIBuffer = new u16[MAXIBUFFERSIZE];
|
||||||
LIBuffer = new u16[MAXIBUFFERSIZE];
|
LIBuffer = new u16[MAXIBUFFERSIZE];
|
||||||
PIBuffer = new u16[MAXIBUFFERSIZE];
|
PIBuffer = new u16[MAXIBUFFERSIZE];
|
||||||
|
|
||||||
s_pCurBufferPointer = LocalVBuffer;
|
s_pCurBufferPointer = LocalVBuffer;
|
||||||
s_pBaseBufferPointer = LocalVBuffer;
|
s_pBaseBufferPointer = LocalVBuffer;
|
||||||
|
|
||||||
Flushed = false;
|
Flushed = false;
|
||||||
|
|
||||||
IndexGenerator::Start(TIBuffer, LIBuffer, PIBuffer);
|
IndexGenerator::Start(TIBuffer, LIBuffer, PIBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
VertexManagerBase::~VertexManagerBase()
|
VertexManagerBase::~VertexManagerBase()
|
||||||
{
|
{
|
||||||
delete[] LocalVBuffer;
|
delete[] LocalVBuffer;
|
||||||
delete[] TIBuffer;
|
delete[] TIBuffer;
|
||||||
delete[] LIBuffer;
|
delete[] LIBuffer;
|
||||||
delete[] PIBuffer;
|
delete[] PIBuffer;
|
||||||
|
|
||||||
// most likely not needed
|
// most likely not needed
|
||||||
ResetBuffer();
|
ResetBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexManagerBase::AddIndices(int _primitive, int _numVertices)
|
void VertexManagerBase::AddIndices(int _primitive, int _numVertices)
|
||||||
{
|
{
|
||||||
switch (_primitive)
|
switch (_primitive)
|
||||||
{
|
{
|
||||||
case GX_DRAW_QUADS:
|
case GX_DRAW_QUADS:
|
||||||
IndexGenerator::AddQuads(_numVertices);
|
IndexGenerator::AddQuads(_numVertices);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GX_DRAW_TRIANGLES:
|
case GX_DRAW_TRIANGLES:
|
||||||
IndexGenerator::AddList(_numVertices);
|
IndexGenerator::AddList(_numVertices);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GX_DRAW_TRIANGLE_STRIP:
|
case GX_DRAW_TRIANGLE_STRIP:
|
||||||
IndexGenerator::AddStrip(_numVertices);
|
IndexGenerator::AddStrip(_numVertices);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GX_DRAW_TRIANGLE_FAN:
|
case GX_DRAW_TRIANGLE_FAN:
|
||||||
IndexGenerator::AddFan(_numVertices);
|
IndexGenerator::AddFan(_numVertices);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GX_DRAW_LINE_STRIP:
|
case GX_DRAW_LINE_STRIP:
|
||||||
IndexGenerator::AddLineStrip(_numVertices);
|
IndexGenerator::AddLineStrip(_numVertices);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GX_DRAW_LINES:
|
case GX_DRAW_LINES:
|
||||||
IndexGenerator::AddLineList(_numVertices);
|
IndexGenerator::AddLineList(_numVertices);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GX_DRAW_POINTS:
|
case GX_DRAW_POINTS:
|
||||||
IndexGenerator::AddPoints(_numVertices);
|
IndexGenerator::AddPoints(_numVertices);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int VertexManager::GetRemainingSize()
|
int VertexManager::GetRemainingSize()
|
||||||
{
|
{
|
||||||
return VertexManagerBase::GetRemainingSize();
|
return VertexManagerBase::GetRemainingSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
int VertexManagerBase::GetRemainingSize()
|
int VertexManagerBase::GetRemainingSize()
|
||||||
{
|
{
|
||||||
return MAXVBUFFERSIZE - (int)(s_pCurBufferPointer - LocalVBuffer);
|
return MAXVBUFFERSIZE - (int)(s_pCurBufferPointer - LocalVBuffer);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int VertexManagerBase::GetRemainingVertices(int primitive)
|
int VertexManagerBase::GetRemainingVertices(int primitive)
|
||||||
{
|
{
|
||||||
switch (primitive)
|
switch (primitive)
|
||||||
{
|
{
|
||||||
case GX_DRAW_QUADS:
|
case GX_DRAW_QUADS:
|
||||||
case GX_DRAW_TRIANGLES:
|
case GX_DRAW_TRIANGLES:
|
||||||
case GX_DRAW_TRIANGLE_STRIP:
|
case GX_DRAW_TRIANGLE_STRIP:
|
||||||
case GX_DRAW_TRIANGLE_FAN:
|
case GX_DRAW_TRIANGLE_FAN:
|
||||||
return (MAXIBUFFERSIZE - IndexGenerator::GetTriangleindexLen()) / 3;
|
return (MAXIBUFFERSIZE - IndexGenerator::GetTriangleindexLen()) / 3;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GX_DRAW_LINE_STRIP:
|
case GX_DRAW_LINE_STRIP:
|
||||||
case GX_DRAW_LINES:
|
case GX_DRAW_LINES:
|
||||||
return (MAXIBUFFERSIZE - IndexGenerator::GetLineindexLen()) / 2;
|
return (MAXIBUFFERSIZE - IndexGenerator::GetLineindexLen()) / 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GX_DRAW_POINTS:
|
case GX_DRAW_POINTS:
|
||||||
return (MAXIBUFFERSIZE - IndexGenerator::GetPointindexLen());
|
return (MAXIBUFFERSIZE - IndexGenerator::GetPointindexLen());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexManager::AddVertices(int _primitive, int _numVertices)
|
void VertexManager::AddVertices(int _primitive, int _numVertices)
|
||||||
{
|
{
|
||||||
VertexManagerBase::AddVertices(_primitive, _numVertices);
|
VertexManagerBase::AddVertices(_primitive, _numVertices);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexManagerBase::AddVertices(int _primitive, int _numVertices)
|
void VertexManagerBase::AddVertices(int _primitive, int _numVertices)
|
||||||
{
|
{
|
||||||
if (_numVertices <= 0)
|
if (_numVertices <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch (_primitive)
|
switch (_primitive)
|
||||||
{
|
{
|
||||||
case GX_DRAW_QUADS:
|
case GX_DRAW_QUADS:
|
||||||
case GX_DRAW_TRIANGLES:
|
case GX_DRAW_TRIANGLES:
|
||||||
case GX_DRAW_TRIANGLE_STRIP:
|
case GX_DRAW_TRIANGLE_STRIP:
|
||||||
case GX_DRAW_TRIANGLE_FAN:
|
case GX_DRAW_TRIANGLE_FAN:
|
||||||
if (MAXIBUFFERSIZE - IndexGenerator::GetTriangleindexLen() < 3 * _numVertices)
|
if (MAXIBUFFERSIZE - IndexGenerator::GetTriangleindexLen() < 3 * _numVertices)
|
||||||
g_vertex_manager->Flush();
|
g_vertex_manager->Flush();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GX_DRAW_LINE_STRIP:
|
case GX_DRAW_LINE_STRIP:
|
||||||
case GX_DRAW_LINES:
|
case GX_DRAW_LINES:
|
||||||
if (MAXIBUFFERSIZE - IndexGenerator::GetLineindexLen() < 2 * _numVertices)
|
if (MAXIBUFFERSIZE - IndexGenerator::GetLineindexLen() < 2 * _numVertices)
|
||||||
g_vertex_manager->Flush();
|
g_vertex_manager->Flush();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GX_DRAW_POINTS:
|
case GX_DRAW_POINTS:
|
||||||
if (MAXIBUFFERSIZE - IndexGenerator::GetPointindexLen() < _numVertices)
|
if (MAXIBUFFERSIZE - IndexGenerator::GetPointindexLen() < _numVertices)
|
||||||
g_vertex_manager->Flush();
|
g_vertex_manager->Flush();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Flushed)
|
if (Flushed)
|
||||||
{
|
{
|
||||||
IndexGenerator::Start(TIBuffer, LIBuffer, PIBuffer);
|
IndexGenerator::Start(TIBuffer, LIBuffer, PIBuffer);
|
||||||
Flushed = false;
|
Flushed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastPrimitive = _primitive;
|
lastPrimitive = _primitive;
|
||||||
ADDSTAT(stats.thisFrame.numPrims, _numVertices);
|
ADDSTAT(stats.thisFrame.numPrims, _numVertices);
|
||||||
INCSTAT(stats.thisFrame.numPrimitiveJoins);
|
INCSTAT(stats.thisFrame.numPrimitiveJoins);
|
||||||
AddIndices(_primitive, _numVertices);
|
AddIndices(_primitive, _numVertices);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexManager::Flush()
|
void VertexManager::Flush()
|
||||||
{
|
{
|
||||||
VertexManagerBase::Flush();
|
VertexManagerBase::Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexManagerBase::Flush()
|
void VertexManagerBase::Flush()
|
||||||
{
|
{
|
||||||
if (LocalVBuffer == s_pCurBufferPointer)
|
if (LocalVBuffer == s_pCurBufferPointer)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (Flushed)
|
if (Flushed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Flushed = true;
|
Flushed = true;
|
||||||
|
|
||||||
VideoFifo_CheckEFBAccess();
|
VideoFifo_CheckEFBAccess();
|
||||||
|
|
||||||
DVSTARTPROFILE();
|
DVSTARTPROFILE();
|
||||||
|
|
||||||
u32 usedtextures = 0;
|
u32 usedtextures = 0;
|
||||||
for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages + 1; ++i)
|
for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages + 1; ++i)
|
||||||
{
|
{
|
||||||
if (bpmem.tevorders[i/2].getEnable(i & 1))
|
if (bpmem.tevorders[i/2].getEnable(i & 1))
|
||||||
usedtextures |= 1 << bpmem.tevorders[i/2].getTexMap(i & 1);
|
usedtextures |= 1 << bpmem.tevorders[i/2].getTexMap(i & 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bpmem.genMode.numindstages > 0)
|
if (bpmem.genMode.numindstages > 0)
|
||||||
for (unsigned int i = 0; i < bpmem.genMode.numtevstages + 1; ++i)
|
for (unsigned int i = 0; i < bpmem.genMode.numtevstages + 1; ++i)
|
||||||
if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages)
|
if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages)
|
||||||
usedtextures |= 1 << bpmem.tevindref.getTexMap(bpmem.tevind[i].bt);
|
usedtextures |= 1 << bpmem.tevindref.getTexMap(bpmem.tevind[i].bt);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < 8; ++i)
|
for (unsigned int i = 0; i < 8; ++i)
|
||||||
{
|
{
|
||||||
if (usedtextures & (1 << i))
|
if (usedtextures & (1 << i))
|
||||||
{
|
{
|
||||||
g_renderer->SetSamplerState(i & 3, i >> 2);
|
g_renderer->SetSamplerState(i & 3, i >> 2);
|
||||||
|
|
||||||
FourTexUnits &tex = bpmem.tex[i >> 2];
|
FourTexUnits &tex = bpmem.tex[i >> 2];
|
||||||
|
|
||||||
TextureCacheBase::TCacheEntryBase* tentry = g_texture_cache->Load(i,
|
TextureCacheBase::TCacheEntryBase* tentry = g_texture_cache->Load(i,
|
||||||
(tex.texImage3[i&3].image_base/* & 0x1FFFFF*/) << 5,
|
(tex.texImage3[i&3].image_base/* & 0x1FFFFF*/) << 5,
|
||||||
tex.texImage0[i&3].width + 1, tex.texImage0[i&3].height + 1,
|
tex.texImage0[i&3].width + 1, tex.texImage0[i&3].height + 1,
|
||||||
tex.texImage0[i&3].format, tex.texTlut[i&3].tmem_offset<<9,
|
tex.texImage0[i&3].format, tex.texTlut[i&3].tmem_offset<<9,
|
||||||
tex.texTlut[i&3].tlut_format,
|
tex.texTlut[i&3].tlut_format,
|
||||||
(tex.texMode0[i&3].min_filter & 3) && (tex.texMode0[i&3].min_filter != 8) && g_ActiveConfig.bUseNativeMips,
|
(tex.texMode0[i&3].min_filter & 3) && (tex.texMode0[i&3].min_filter != 8) && g_ActiveConfig.bUseNativeMips,
|
||||||
(tex.texMode1[i&3].max_lod >> 4));
|
(tex.texMode1[i&3].max_lod >> 4));
|
||||||
|
|
||||||
if (tentry)
|
if (tentry)
|
||||||
PixelShaderManager::SetTexDims(i, tentry->w, tentry->h, 0, 0);
|
PixelShaderManager::SetTexDims(i, tentry->w, tentry->h, 0, 0);
|
||||||
else
|
else
|
||||||
ERROR_LOG(VIDEO, "error loading texture");
|
ERROR_LOG(VIDEO, "error loading texture");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VertexShaderManager::SetConstants();
|
VertexShaderManager::SetConstants();
|
||||||
PixelShaderManager::SetConstants();
|
PixelShaderManager::SetConstants();
|
||||||
|
|
||||||
if (false == g_pixel_shader_cache->SetShader(false))
|
if (false == g_pixel_shader_cache->SetShader(false))
|
||||||
goto shader_fail;
|
goto shader_fail;
|
||||||
|
|
||||||
if (false == g_vertex_shader_cache->SetShader(g_nativeVertexFmt->m_components))
|
if (false == g_vertex_shader_cache->SetShader(g_nativeVertexFmt->m_components))
|
||||||
goto shader_fail;
|
goto shader_fail;
|
||||||
|
|
||||||
const unsigned int stride = g_nativeVertexFmt->GetVertexStride();
|
const unsigned int stride = g_nativeVertexFmt->GetVertexStride();
|
||||||
g_nativeVertexFmt->SetupVertexPointers();
|
g_nativeVertexFmt->SetupVertexPointers();
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
g_vertex_manager->Draw(stride, false);
|
g_vertex_manager->Draw(stride, false);
|
||||||
|
|
||||||
if (false == g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate)
|
if (false == g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate)
|
||||||
{
|
{
|
||||||
if (false == g_pixel_shader_cache->SetShader(true))
|
if (false == g_pixel_shader_cache->SetShader(true))
|
||||||
goto shader_fail;
|
goto shader_fail;
|
||||||
|
|
||||||
// update alpha only
|
// update alpha only
|
||||||
g_vertex_manager->Draw(stride, true);
|
g_vertex_manager->Draw(stride, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
//IndexGenerator::Start(TIBuffer, LIBuffer, PIBuffer);
|
//IndexGenerator::Start(TIBuffer, LIBuffer, PIBuffer);
|
||||||
|
|
||||||
shader_fail:
|
shader_fail:
|
||||||
ResetBuffer();
|
ResetBuffer();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,47 +1,47 @@
|
|||||||
|
|
||||||
#ifndef _VERTExMANAGER_H_
|
#ifndef _VERTExMANAGER_H_
|
||||||
#define _VERTExMANAGER_H_
|
#define _VERTExMANAGER_H_
|
||||||
|
|
||||||
#include "NativeVertexFormat.h"
|
#include "NativeVertexFormat.h"
|
||||||
#include "NativeVertexWriter.h"
|
#include "NativeVertexWriter.h"
|
||||||
#include "BPMemory.h"
|
#include "BPMemory.h"
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
MAXVBUFFERSIZE = 0x50000,
|
MAXVBUFFERSIZE = 0x50000,
|
||||||
MAXIBUFFERSIZE = 0x10000,
|
MAXIBUFFERSIZE = 0x10000,
|
||||||
};
|
};
|
||||||
|
|
||||||
using VertexManager::s_pBaseBufferPointer;
|
using VertexManager::s_pBaseBufferPointer;
|
||||||
using VertexManager::s_pCurBufferPointer;
|
using VertexManager::s_pCurBufferPointer;
|
||||||
|
|
||||||
extern NativeVertexFormat *g_nativeVertexFmt;
|
extern NativeVertexFormat *g_nativeVertexFmt;
|
||||||
|
|
||||||
class VertexManagerBase
|
class VertexManagerBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
VertexManagerBase();
|
VertexManagerBase();
|
||||||
virtual ~VertexManagerBase();
|
virtual ~VertexManagerBase();
|
||||||
|
|
||||||
static void Flush();
|
static void Flush();
|
||||||
virtual void Draw(u32 stride, bool alphapass) = 0;
|
virtual void Draw(u32 stride, bool alphapass) = 0;
|
||||||
|
|
||||||
virtual NativeVertexFormat* CreateNativeVertexFormat() = 0;
|
virtual NativeVertexFormat* CreateNativeVertexFormat() = 0;
|
||||||
|
|
||||||
static void AddIndices(int _primitive, int _numVertices);
|
static void AddIndices(int _primitive, int _numVertices);
|
||||||
static int GetRemainingSize();
|
static int GetRemainingSize();
|
||||||
static int GetRemainingVertices(int primitive);
|
static int GetRemainingVertices(int primitive);
|
||||||
static void AddVertices(int _primitive, int _numVertices);
|
static void AddVertices(int _primitive, int _numVertices);
|
||||||
static void ResetBuffer();
|
static void ResetBuffer();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static u16* TIBuffer;
|
static u16* TIBuffer;
|
||||||
static u16* LIBuffer;
|
static u16* LIBuffer;
|
||||||
static u16* PIBuffer;
|
static u16* PIBuffer;
|
||||||
static bool Flushed;
|
static bool Flushed;
|
||||||
|
|
||||||
static int lastPrimitive;
|
static int lastPrimitive;
|
||||||
static u8* LocalVBuffer;
|
static u8* LocalVBuffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,25 +1,25 @@
|
|||||||
|
|
||||||
#include "VertexShaderManager.h"
|
#include "VertexShaderManager.h"
|
||||||
|
|
||||||
#include "Main.h"
|
#include "Main.h"
|
||||||
#include "VertexShaderCache.h"
|
#include "VertexShaderCache.h"
|
||||||
|
|
||||||
void SetVSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4)
|
void SetVSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4)
|
||||||
{
|
{
|
||||||
g_vertex_shader_cache->SetVSConstant4f(const_number, f1, f2, f3, f4);
|
g_vertex_shader_cache->SetVSConstant4f(const_number, f1, f2, f3, f4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetVSConstant4fv(unsigned int const_number, const float* f)
|
void SetVSConstant4fv(unsigned int const_number, const float* f)
|
||||||
{
|
{
|
||||||
g_vertex_shader_cache->SetVSConstant4fv(const_number, f);
|
g_vertex_shader_cache->SetVSConstant4fv(const_number, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetMultiVSConstant3fv(unsigned int const_number, unsigned int count, const float* f)
|
void SetMultiVSConstant3fv(unsigned int const_number, unsigned int count, const float* f)
|
||||||
{
|
{
|
||||||
g_vertex_shader_cache->SetMultiVSConstant3fv(const_number, count, f);
|
g_vertex_shader_cache->SetMultiVSConstant3fv(const_number, count, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetMultiVSConstant4fv(unsigned int const_number, unsigned int count, const float* f)
|
void SetMultiVSConstant4fv(unsigned int const_number, unsigned int count, const float* f)
|
||||||
{
|
{
|
||||||
g_vertex_shader_cache->SetMultiVSConstant4fv(const_number, count, f);
|
g_vertex_shader_cache->SetMultiVSConstant4fv(const_number, count, f);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
|
|
||||||
#ifndef _VERTEXSHADERCACHE_H_
|
#ifndef _VERTEXSHADERCACHE_H_
|
||||||
#define _VERTEXSHADERCACHE_H_
|
#define _VERTEXSHADERCACHE_H_
|
||||||
|
|
||||||
class VertexShaderCacheBase
|
class VertexShaderCacheBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~VertexShaderCacheBase() {}
|
virtual ~VertexShaderCacheBase() {}
|
||||||
|
|
||||||
virtual bool SetShader(u32 components) = 0;
|
virtual bool SetShader(u32 components) = 0;
|
||||||
|
|
||||||
virtual void SetVSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4) = 0;
|
virtual void SetVSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4) = 0;
|
||||||
virtual void SetVSConstant4fv(unsigned int const_number, const float* f) = 0;
|
virtual void SetVSConstant4fv(unsigned int const_number, const float* f) = 0;
|
||||||
virtual void SetMultiVSConstant3fv(unsigned int const_number, unsigned int count, const float* f) = 0;
|
virtual void SetMultiVSConstant3fv(unsigned int const_number, unsigned int count, const float* f) = 0;
|
||||||
virtual void SetMultiVSConstant4fv(unsigned int const_number, unsigned int count, const float* f) = 0;
|
virtual void SetMultiVSConstant4fv(unsigned int const_number, unsigned int count, const float* f) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,245 +1,245 @@
|
|||||||
|
|
||||||
#include "VideoConfigDiag.h"
|
#include "VideoConfigDiag.h"
|
||||||
|
|
||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
#include "Main.h"
|
#include "Main.h"
|
||||||
|
|
||||||
#define _connect_macro_(b, f, c, s) (b)->Connect(wxID_ANY, (c), wxCommandEventHandler( f ), (wxObject*)0, (wxEvtHandler*)s)
|
#define _connect_macro_(b, f, c, s) (b)->Connect(wxID_ANY, (c), wxCommandEventHandler( f ), (wxObject*)0, (wxEvtHandler*)s)
|
||||||
|
|
||||||
// template instantiation
|
// template instantiation
|
||||||
template class BoolSetting<wxCheckBox>;
|
template class BoolSetting<wxCheckBox>;
|
||||||
template class BoolSetting<wxRadioButton>;
|
template class BoolSetting<wxRadioButton>;
|
||||||
|
|
||||||
typedef BoolSetting<wxCheckBox> SettingCheckBox;
|
typedef BoolSetting<wxCheckBox> SettingCheckBox;
|
||||||
typedef BoolSetting<wxRadioButton> SettingRadioButton;
|
typedef BoolSetting<wxRadioButton> SettingRadioButton;
|
||||||
|
|
||||||
SettingCheckBox::BoolSetting(wxWindow* parent, const wxString& label, bool &setting, bool reverse, long style)
|
SettingCheckBox::BoolSetting(wxWindow* parent, const wxString& label, bool &setting, bool reverse, long style)
|
||||||
: wxCheckBox(parent, -1, label, wxDefaultPosition, wxDefaultSize, style)
|
: wxCheckBox(parent, -1, label, wxDefaultPosition, wxDefaultSize, style)
|
||||||
, m_setting(setting)
|
, m_setting(setting)
|
||||||
, m_reverse(reverse)
|
, m_reverse(reverse)
|
||||||
{
|
{
|
||||||
SetValue(m_setting ^ m_reverse);
|
SetValue(m_setting ^ m_reverse);
|
||||||
_connect_macro_(this, BoolSetting<W>::UpdateValue, wxEVT_COMMAND_CHECKBOX_CLICKED, this);
|
_connect_macro_(this, BoolSetting<W>::UpdateValue, wxEVT_COMMAND_CHECKBOX_CLICKED, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
SettingRadioButton::BoolSetting(wxWindow* parent, const wxString& label, bool &setting, bool reverse, long style)
|
SettingRadioButton::BoolSetting(wxWindow* parent, const wxString& label, bool &setting, bool reverse, long style)
|
||||||
: wxRadioButton(parent, -1, label, wxDefaultPosition, wxDefaultSize, style)
|
: wxRadioButton(parent, -1, label, wxDefaultPosition, wxDefaultSize, style)
|
||||||
, m_setting(setting)
|
, m_setting(setting)
|
||||||
, m_reverse(reverse)
|
, m_reverse(reverse)
|
||||||
{
|
{
|
||||||
SetValue(m_setting ^ m_reverse);
|
SetValue(m_setting ^ m_reverse);
|
||||||
_connect_macro_(this, BoolSetting<W>::UpdateValue, wxEVT_COMMAND_RADIOBUTTON_SELECTED, this);
|
_connect_macro_(this, BoolSetting<W>::UpdateValue, wxEVT_COMMAND_RADIOBUTTON_SELECTED, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename W>
|
template <typename W>
|
||||||
void BoolSetting<W>::UpdateValue(wxCommandEvent& ev)
|
void BoolSetting<W>::UpdateValue(wxCommandEvent& ev)
|
||||||
{
|
{
|
||||||
m_setting = (ev.GetInt() != 0) ^ m_reverse;
|
m_setting = (ev.GetInt() != 0) ^ m_reverse;
|
||||||
}
|
}
|
||||||
|
|
||||||
SettingChoice::SettingChoice(wxWindow* parent, int &setting, int num, const wxString choices[])
|
SettingChoice::SettingChoice(wxWindow* parent, int &setting, int num, const wxString choices[])
|
||||||
: wxChoice(parent, -1, wxDefaultPosition, wxDefaultSize, num, choices)
|
: wxChoice(parent, -1, wxDefaultPosition, wxDefaultSize, num, choices)
|
||||||
, m_setting(setting)
|
, m_setting(setting)
|
||||||
{
|
{
|
||||||
Select(m_setting);
|
Select(m_setting);
|
||||||
_connect_macro_(this, SettingChoice::UpdateValue, wxEVT_COMMAND_CHOICE_SELECTED, this);
|
_connect_macro_(this, SettingChoice::UpdateValue, wxEVT_COMMAND_CHOICE_SELECTED, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingChoice::UpdateValue(wxCommandEvent& ev)
|
void SettingChoice::UpdateValue(wxCommandEvent& ev)
|
||||||
{
|
{
|
||||||
m_setting = ev.GetInt();
|
m_setting = ev.GetInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoConfigDiag::CloseDiag(wxCommandEvent&)
|
void VideoConfigDiag::CloseDiag(wxCommandEvent&)
|
||||||
{
|
{
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoConfigDiag::VideoConfigDiag(wxWindow* parent)
|
VideoConfigDiag::VideoConfigDiag(wxWindow* parent)
|
||||||
: wxDialog(parent, -1, wxT("Dolphin Graphics Configuration"), wxDefaultPosition, wxDefaultSize)
|
: wxDialog(parent, -1, wxT("Dolphin Graphics Configuration"), wxDefaultPosition, wxDefaultSize)
|
||||||
{
|
{
|
||||||
VideoConfig &vconfig = g_Config;
|
VideoConfig &vconfig = g_Config;
|
||||||
|
|
||||||
wxNotebook* const notebook = new wxNotebook(this, -1, wxDefaultPosition, wxDefaultSize);
|
wxNotebook* const notebook = new wxNotebook(this, -1, wxDefaultPosition, wxDefaultSize);
|
||||||
|
|
||||||
// -- GENERAL --
|
// -- GENERAL --
|
||||||
{
|
{
|
||||||
wxPanel* const page_general = new wxPanel(notebook, -1, wxDefaultPosition);
|
wxPanel* const page_general = new wxPanel(notebook, -1, wxDefaultPosition);
|
||||||
notebook->AddPage(page_general, wxT("General"));
|
notebook->AddPage(page_general, wxT("General"));
|
||||||
wxBoxSizer* const szr_general = new wxBoxSizer(wxVERTICAL);
|
wxBoxSizer* const szr_general = new wxBoxSizer(wxVERTICAL);
|
||||||
|
|
||||||
// - basic
|
// - basic
|
||||||
{
|
{
|
||||||
wxStaticBoxSizer* const group_basic = new wxStaticBoxSizer(wxVERTICAL, page_general, wxT("Basic"));
|
wxStaticBoxSizer* const group_basic = new wxStaticBoxSizer(wxVERTICAL, page_general, wxT("Basic"));
|
||||||
szr_general->Add(group_basic, 0, wxEXPAND | wxALL, 5);
|
szr_general->Add(group_basic, 0, wxEXPAND | wxALL, 5);
|
||||||
wxFlexGridSizer* const szr_basic = new wxFlexGridSizer(2, 5, 5);
|
wxFlexGridSizer* const szr_basic = new wxFlexGridSizer(2, 5, 5);
|
||||||
group_basic->Add(szr_basic, 1, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
group_basic->Add(szr_basic, 1, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
||||||
|
|
||||||
// graphics api
|
// graphics api
|
||||||
{
|
{
|
||||||
const wxString gfxapi_choices[] = { wxT("Software [not present]"),
|
const wxString gfxapi_choices[] = { wxT("Software [not present]"),
|
||||||
wxT("OpenGL [broken]"), wxT("Direct3D 9 [broken]"), wxT("Direct3D 11") };
|
wxT("OpenGL [broken]"), wxT("Direct3D 9 [broken]"), wxT("Direct3D 11") };
|
||||||
|
|
||||||
szr_basic->Add(new wxStaticText(page_general, -1, wxT("Graphics API:")), 1, wxALIGN_CENTER_VERTICAL, 0);
|
szr_basic->Add(new wxStaticText(page_general, -1, wxT("Graphics API:")), 1, wxALIGN_CENTER_VERTICAL, 0);
|
||||||
wxChoice* const choice_gfxapi = new SettingChoice(page_general,
|
wxChoice* const choice_gfxapi = new SettingChoice(page_general,
|
||||||
g_gfxapi, sizeof(gfxapi_choices)/sizeof(*gfxapi_choices), gfxapi_choices);
|
g_gfxapi, sizeof(gfxapi_choices)/sizeof(*gfxapi_choices), gfxapi_choices);
|
||||||
szr_basic->Add(choice_gfxapi, 1, 0, 0);
|
szr_basic->Add(choice_gfxapi, 1, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// for D3D only
|
// for D3D only
|
||||||
// adapter
|
// adapter
|
||||||
{
|
{
|
||||||
//szr_basic->Add(new wxStaticText(page_general, -1, wxT("Adapter:")), 1, wxALIGN_CENTER_VERTICAL, 5);
|
//szr_basic->Add(new wxStaticText(page_general, -1, wxT("Adapter:")), 1, wxALIGN_CENTER_VERTICAL, 5);
|
||||||
//wxChoice* const choice_adapter = new SettingChoice(page_general, vconfig.iAdapter);
|
//wxChoice* const choice_adapter = new SettingChoice(page_general, vconfig.iAdapter);
|
||||||
//szr_basic->Add(choice_adapter, 1, 0, 0);
|
//szr_basic->Add(choice_adapter, 1, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// aspect-ratio
|
// aspect-ratio
|
||||||
{
|
{
|
||||||
const wxString ar_choices[] = { wxT("Auto [recommended]"),
|
const wxString ar_choices[] = { wxT("Auto [recommended]"),
|
||||||
wxT("Force 16:9"), wxT("Force 4:3"), wxT("Strech to Window") };
|
wxT("Force 16:9"), wxT("Force 4:3"), wxT("Strech to Window") };
|
||||||
|
|
||||||
szr_basic->Add(new wxStaticText(page_general, -1, wxT("Aspect ratio:")), 1, wxALIGN_CENTER_VERTICAL, 0);
|
szr_basic->Add(new wxStaticText(page_general, -1, wxT("Aspect ratio:")), 1, wxALIGN_CENTER_VERTICAL, 0);
|
||||||
wxChoice* const choice_aspect = new SettingChoice(page_general,
|
wxChoice* const choice_aspect = new SettingChoice(page_general,
|
||||||
vconfig.iAspectRatio, sizeof(ar_choices)/sizeof(*ar_choices), ar_choices);
|
vconfig.iAspectRatio, sizeof(ar_choices)/sizeof(*ar_choices), ar_choices);
|
||||||
szr_basic->Add(choice_aspect, 1, 0, 0);
|
szr_basic->Add(choice_aspect, 1, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// widescreen hack
|
// widescreen hack
|
||||||
{
|
{
|
||||||
szr_basic->AddStretchSpacer(1);
|
szr_basic->AddStretchSpacer(1);
|
||||||
szr_basic->Add(new SettingCheckBox(page_general, wxT("Widescreen Hack"), vconfig.bWidescreenHack), 1, 0, 0);
|
szr_basic->Add(new SettingCheckBox(page_general, wxT("Widescreen Hack"), vconfig.bWidescreenHack), 1, 0, 0);
|
||||||
szr_basic->AddStretchSpacer(1);
|
szr_basic->AddStretchSpacer(1);
|
||||||
szr_basic->Add(new SettingCheckBox(page_general, wxT("V-Sync"), vconfig.bVSync), 1, 0, 0);
|
szr_basic->Add(new SettingCheckBox(page_general, wxT("V-Sync"), vconfig.bVSync), 1, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - EFB
|
// - EFB
|
||||||
{
|
{
|
||||||
wxStaticBoxSizer* const group_efb = new wxStaticBoxSizer(wxVERTICAL, page_general, wxT("EFB"));
|
wxStaticBoxSizer* const group_efb = new wxStaticBoxSizer(wxVERTICAL, page_general, wxT("EFB"));
|
||||||
szr_general->Add(group_efb, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
szr_general->Add(group_efb, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
||||||
|
|
||||||
group_efb->Add(new SettingCheckBox(page_general, wxT("Enable CPU Access"), vconfig.bEFBAccessEnable), 0, wxBOTTOM | wxLEFT, 5);
|
group_efb->Add(new SettingCheckBox(page_general, wxT("Enable CPU Access"), vconfig.bEFBAccessEnable), 0, wxBOTTOM | wxLEFT, 5);
|
||||||
|
|
||||||
// EFB scale
|
// EFB scale
|
||||||
{
|
{
|
||||||
// TODO: give this a label
|
// TODO: give this a label
|
||||||
const wxString efbscale_choices[] = { wxT("Fractional"), wxT("Integral [recommended]"),
|
const wxString efbscale_choices[] = { wxT("Fractional"), wxT("Integral [recommended]"),
|
||||||
wxT("1x"), wxT("2x"), wxT("3x")/*, wxT("4x")*/ };
|
wxT("1x"), wxT("2x"), wxT("3x")/*, wxT("4x")*/ };
|
||||||
|
|
||||||
wxChoice *const choice_efbscale = new SettingChoice(page_general,
|
wxChoice *const choice_efbscale = new SettingChoice(page_general,
|
||||||
vconfig.iEFBScale, sizeof(efbscale_choices)/sizeof(*efbscale_choices), efbscale_choices);
|
vconfig.iEFBScale, sizeof(efbscale_choices)/sizeof(*efbscale_choices), efbscale_choices);
|
||||||
group_efb->Add(choice_efbscale, 0, wxBOTTOM | wxLEFT, 5);
|
group_efb->Add(choice_efbscale, 0, wxBOTTOM | wxLEFT, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
// EFB copy
|
// EFB copy
|
||||||
wxStaticBoxSizer* const group_efbcopy = new wxStaticBoxSizer(wxHORIZONTAL, page_general, wxT("Copy"));
|
wxStaticBoxSizer* const group_efbcopy = new wxStaticBoxSizer(wxHORIZONTAL, page_general, wxT("Copy"));
|
||||||
group_efb->Add(group_efbcopy, 0, wxEXPAND | wxBOTTOM, 5);
|
group_efb->Add(group_efbcopy, 0, wxEXPAND | wxBOTTOM, 5);
|
||||||
|
|
||||||
group_efbcopy->Add(new SettingCheckBox(page_general, wxT("Enable"), vconfig.bEFBCopyDisable, true), 0, wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
group_efbcopy->Add(new SettingCheckBox(page_general, wxT("Enable"), vconfig.bEFBCopyDisable, true), 0, wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
||||||
group_efbcopy->AddStretchSpacer(1);
|
group_efbcopy->AddStretchSpacer(1);
|
||||||
group_efbcopy->Add(new SettingRadioButton(page_general, wxT("Texture"), vconfig.bCopyEFBToTexture, false, wxRB_GROUP), 0, wxRIGHT, 5);
|
group_efbcopy->Add(new SettingRadioButton(page_general, wxT("Texture"), vconfig.bCopyEFBToTexture, false, wxRB_GROUP), 0, wxRIGHT, 5);
|
||||||
group_efbcopy->Add(new SettingRadioButton(page_general, wxT("RAM"), vconfig.bCopyEFBToTexture, true), 0, wxRIGHT, 5);
|
group_efbcopy->Add(new SettingRadioButton(page_general, wxT("RAM"), vconfig.bCopyEFBToTexture, true), 0, wxRIGHT, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - safe texture cache
|
// - safe texture cache
|
||||||
{
|
{
|
||||||
wxStaticBoxSizer* const group_safetex = new wxStaticBoxSizer(wxHORIZONTAL, page_general, wxT("Safe Texture Cache"));
|
wxStaticBoxSizer* const group_safetex = new wxStaticBoxSizer(wxHORIZONTAL, page_general, wxT("Safe Texture Cache"));
|
||||||
szr_general->Add(group_safetex, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
szr_general->Add(group_safetex, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
||||||
|
|
||||||
// safe texture cache
|
// safe texture cache
|
||||||
group_safetex->Add(new SettingCheckBox(page_general, wxT("Enable"), vconfig.bSafeTextureCache), 0, wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
group_safetex->Add(new SettingCheckBox(page_general, wxT("Enable"), vconfig.bSafeTextureCache), 0, wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
||||||
group_safetex->AddStretchSpacer(1);
|
group_safetex->AddStretchSpacer(1);
|
||||||
// TODO: make these radio buttons functional
|
// TODO: make these radio buttons functional
|
||||||
//group_safetex->Add(new wxRadioButton(page_general, -1, wxT("Safe"),
|
//group_safetex->Add(new wxRadioButton(page_general, -1, wxT("Safe"),
|
||||||
// wxDefaultPosition, wxDefaultSize, wxRB_GROUP), 0, wxRIGHT, 5);
|
// wxDefaultPosition, wxDefaultSize, wxRB_GROUP), 0, wxRIGHT, 5);
|
||||||
//group_safetex->Add(new wxRadioButton(page_general, -1, wxT("Normal")), 0, wxRIGHT, 5);
|
//group_safetex->Add(new wxRadioButton(page_general, -1, wxT("Normal")), 0, wxRIGHT, 5);
|
||||||
//group_safetex->Add(new wxRadioButton(page_general, -1, wxT("Fast")), 0, wxRIGHT, 5);
|
//group_safetex->Add(new wxRadioButton(page_general, -1, wxT("Fast")), 0, wxRIGHT, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
page_general->SetSizerAndFit(szr_general);
|
page_general->SetSizerAndFit(szr_general);
|
||||||
}
|
}
|
||||||
|
|
||||||
// -- ADVANCED --
|
// -- ADVANCED --
|
||||||
{
|
{
|
||||||
wxPanel* const page_advanced = new wxPanel(notebook, -1, wxDefaultPosition);
|
wxPanel* const page_advanced = new wxPanel(notebook, -1, wxDefaultPosition);
|
||||||
notebook->AddPage(page_advanced, wxT("Advanced"));
|
notebook->AddPage(page_advanced, wxT("Advanced"));
|
||||||
wxBoxSizer* const szr_advanced = new wxBoxSizer(wxVERTICAL);
|
wxBoxSizer* const szr_advanced = new wxBoxSizer(wxVERTICAL);
|
||||||
|
|
||||||
// - rendering
|
// - rendering
|
||||||
{
|
{
|
||||||
wxStaticBoxSizer* const group_rendering = new wxStaticBoxSizer(wxVERTICAL, page_advanced, wxT("Rendering"));
|
wxStaticBoxSizer* const group_rendering = new wxStaticBoxSizer(wxVERTICAL, page_advanced, wxT("Rendering"));
|
||||||
szr_advanced->Add(group_rendering, 0, wxEXPAND | wxALL, 5);
|
szr_advanced->Add(group_rendering, 0, wxEXPAND | wxALL, 5);
|
||||||
wxGridSizer* const szr_rendering = new wxGridSizer(2, 5, 5);
|
wxGridSizer* const szr_rendering = new wxGridSizer(2, 5, 5);
|
||||||
group_rendering->Add(szr_rendering, 1, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
group_rendering->Add(szr_rendering, 1, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
||||||
|
|
||||||
szr_rendering->Add(new SettingCheckBox(page_advanced, wxT("Enable Wireframe"), vconfig.bWireFrame));
|
szr_rendering->Add(new SettingCheckBox(page_advanced, wxT("Enable Wireframe"), vconfig.bWireFrame));
|
||||||
szr_rendering->Add(new SettingCheckBox(page_advanced, wxT("Disable Lighting"), vconfig.bDisableLighting));
|
szr_rendering->Add(new SettingCheckBox(page_advanced, wxT("Disable Lighting"), vconfig.bDisableLighting));
|
||||||
szr_rendering->Add(new SettingCheckBox(page_advanced, wxT("Disable Textures"), vconfig.bDisableTexturing));
|
szr_rendering->Add(new SettingCheckBox(page_advanced, wxT("Disable Textures"), vconfig.bDisableTexturing));
|
||||||
szr_rendering->Add(new SettingCheckBox(page_advanced, wxT("Disable Fog"), vconfig.bDisableFog));
|
szr_rendering->Add(new SettingCheckBox(page_advanced, wxT("Disable Fog"), vconfig.bDisableFog));
|
||||||
szr_rendering->Add(new SettingCheckBox(page_advanced, wxT("Disable Dest. Alpha Pass"), vconfig.bDstAlphaPass));
|
szr_rendering->Add(new SettingCheckBox(page_advanced, wxT("Disable Dest. Alpha Pass"), vconfig.bDstAlphaPass));
|
||||||
}
|
}
|
||||||
|
|
||||||
// - info
|
// - info
|
||||||
{
|
{
|
||||||
wxStaticBoxSizer* const group_info = new wxStaticBoxSizer(wxVERTICAL, page_advanced, wxT("Overlay Information"));
|
wxStaticBoxSizer* const group_info = new wxStaticBoxSizer(wxVERTICAL, page_advanced, wxT("Overlay Information"));
|
||||||
szr_advanced->Add(group_info, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
szr_advanced->Add(group_info, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
||||||
wxGridSizer* const szr_info = new wxGridSizer(2, 5, 5);
|
wxGridSizer* const szr_info = new wxGridSizer(2, 5, 5);
|
||||||
group_info->Add(szr_info, 1, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
group_info->Add(szr_info, 1, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
||||||
|
|
||||||
szr_info->Add(new SettingCheckBox(page_advanced, wxT("Show FPS"), vconfig.bShowFPS));
|
szr_info->Add(new SettingCheckBox(page_advanced, wxT("Show FPS"), vconfig.bShowFPS));
|
||||||
szr_info->Add(new SettingCheckBox(page_advanced, wxT("Various Statistics"), vconfig.bOverlayStats));
|
szr_info->Add(new SettingCheckBox(page_advanced, wxT("Various Statistics"), vconfig.bOverlayStats));
|
||||||
szr_info->Add(new SettingCheckBox(page_advanced, wxT("Projection Stats"), vconfig.bOverlayProjStats));
|
szr_info->Add(new SettingCheckBox(page_advanced, wxT("Projection Stats"), vconfig.bOverlayProjStats));
|
||||||
szr_info->Add(new SettingCheckBox(page_advanced, wxT("Texture Format"), vconfig.bTexFmtOverlayEnable));
|
szr_info->Add(new SettingCheckBox(page_advanced, wxT("Texture Format"), vconfig.bTexFmtOverlayEnable));
|
||||||
szr_info->Add(new SettingCheckBox(page_advanced, wxT("EFB Copy Regions"), vconfig.bShowEFBCopyRegions));
|
szr_info->Add(new SettingCheckBox(page_advanced, wxT("EFB Copy Regions"), vconfig.bShowEFBCopyRegions));
|
||||||
}
|
}
|
||||||
|
|
||||||
// - XFB
|
// - XFB
|
||||||
{
|
{
|
||||||
wxStaticBoxSizer* const group_xfb = new wxStaticBoxSizer(wxHORIZONTAL, page_advanced, wxT("XFB"));
|
wxStaticBoxSizer* const group_xfb = new wxStaticBoxSizer(wxHORIZONTAL, page_advanced, wxT("XFB"));
|
||||||
szr_advanced->Add(group_xfb, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
szr_advanced->Add(group_xfb, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
||||||
|
|
||||||
group_xfb->Add(new SettingCheckBox(page_advanced, wxT("Enable"), vconfig.bUseXFB), 0, wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
group_xfb->Add(new SettingCheckBox(page_advanced, wxT("Enable"), vconfig.bUseXFB), 0, wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
||||||
group_xfb->AddStretchSpacer(1);
|
group_xfb->AddStretchSpacer(1);
|
||||||
group_xfb->Add(new SettingRadioButton(page_advanced, wxT("Virtual"), vconfig.bUseRealXFB, true, wxRB_GROUP), 0, wxRIGHT, 5);
|
group_xfb->Add(new SettingRadioButton(page_advanced, wxT("Virtual"), vconfig.bUseRealXFB, true, wxRB_GROUP), 0, wxRIGHT, 5);
|
||||||
group_xfb->Add(new SettingRadioButton(page_advanced, wxT("Real"), vconfig.bUseRealXFB), 0, wxRIGHT, 5);
|
group_xfb->Add(new SettingRadioButton(page_advanced, wxT("Real"), vconfig.bUseRealXFB), 0, wxRIGHT, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - utility
|
// - utility
|
||||||
{
|
{
|
||||||
wxStaticBoxSizer* const group_utility = new wxStaticBoxSizer(wxVERTICAL, page_advanced, wxT("Utility"));
|
wxStaticBoxSizer* const group_utility = new wxStaticBoxSizer(wxVERTICAL, page_advanced, wxT("Utility"));
|
||||||
szr_advanced->Add(group_utility, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
szr_advanced->Add(group_utility, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
||||||
wxGridSizer* const szr_utility = new wxGridSizer(2, 5, 5);
|
wxGridSizer* const szr_utility = new wxGridSizer(2, 5, 5);
|
||||||
group_utility->Add(szr_utility, 1, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
group_utility->Add(szr_utility, 1, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
||||||
|
|
||||||
szr_utility->Add(new SettingCheckBox(page_advanced, wxT("Dump Textures"), vconfig.bDumpTextures));
|
szr_utility->Add(new SettingCheckBox(page_advanced, wxT("Dump Textures"), vconfig.bDumpTextures));
|
||||||
szr_utility->Add(new SettingCheckBox(page_advanced, wxT("Load Hi-Res Textures"), vconfig.bHiresTextures));
|
szr_utility->Add(new SettingCheckBox(page_advanced, wxT("Load Hi-Res Textures"), vconfig.bHiresTextures));
|
||||||
szr_utility->Add(new SettingCheckBox(page_advanced, wxT("Dump EFB Target"), vconfig.bDumpEFBTarget));
|
szr_utility->Add(new SettingCheckBox(page_advanced, wxT("Dump EFB Target"), vconfig.bDumpEFBTarget));
|
||||||
szr_utility->Add(new SettingCheckBox(page_advanced, wxT("Dump Frames"), vconfig.bDumpFrames));
|
szr_utility->Add(new SettingCheckBox(page_advanced, wxT("Dump Frames"), vconfig.bDumpFrames));
|
||||||
szr_utility->Add(new SettingCheckBox(page_advanced, wxT("Free Look"), vconfig.bFreeLook));
|
szr_utility->Add(new SettingCheckBox(page_advanced, wxT("Free Look"), vconfig.bFreeLook));
|
||||||
}
|
}
|
||||||
|
|
||||||
// stuff to move/remove
|
// stuff to move/remove
|
||||||
{
|
{
|
||||||
szr_advanced->Add(new SettingCheckBox(page_advanced, wxT("Load Native Mipmaps"), vconfig.bUseNativeMips), 0, wxBOTTOM | wxLEFT, 5);
|
szr_advanced->Add(new SettingCheckBox(page_advanced, wxT("Load Native Mipmaps"), vconfig.bUseNativeMips), 0, wxBOTTOM | wxLEFT, 5);
|
||||||
szr_advanced->Add(new SettingCheckBox(page_advanced, wxT("EFB Scaled Copy"), vconfig.bCopyEFBScaled), 0, wxBOTTOM | wxLEFT, 5);
|
szr_advanced->Add(new SettingCheckBox(page_advanced, wxT("EFB Scaled Copy"), vconfig.bCopyEFBScaled), 0, wxBOTTOM | wxLEFT, 5);
|
||||||
szr_advanced->Add(new SettingCheckBox(page_advanced, wxT("Auto Scale"), vconfig.bAutoScale), 0, wxBOTTOM | wxLEFT, 5);
|
szr_advanced->Add(new SettingCheckBox(page_advanced, wxT("Auto Scale"), vconfig.bAutoScale), 0, wxBOTTOM | wxLEFT, 5);
|
||||||
szr_advanced->Add(new SettingCheckBox(page_advanced, wxT("Crop"), vconfig.bCrop), 0, wxBOTTOM | wxLEFT, 5);
|
szr_advanced->Add(new SettingCheckBox(page_advanced, wxT("Crop"), vconfig.bCrop), 0, wxBOTTOM | wxLEFT, 5);
|
||||||
szr_advanced->Add(new SettingCheckBox(page_advanced, wxT("Enable OpenCL"), vconfig.bEnableOpenCL), 0, wxBOTTOM | wxLEFT, 5);
|
szr_advanced->Add(new SettingCheckBox(page_advanced, wxT("Enable OpenCL"), vconfig.bEnableOpenCL), 0, wxBOTTOM | wxLEFT, 5);
|
||||||
szr_advanced->Add(new SettingCheckBox(page_advanced, wxT("Enable Display List Caching"), vconfig.bDlistCachingEnable), 0, wxBOTTOM | wxLEFT, 5);
|
szr_advanced->Add(new SettingCheckBox(page_advanced, wxT("Enable Display List Caching"), vconfig.bDlistCachingEnable), 0, wxBOTTOM | wxLEFT, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
page_advanced->SetSizerAndFit(szr_advanced);
|
page_advanced->SetSizerAndFit(szr_advanced);
|
||||||
}
|
}
|
||||||
|
|
||||||
wxButton* const btn_close = new wxButton(this, -1, wxT("Close"), wxDefaultPosition);
|
wxButton* const btn_close = new wxButton(this, -1, wxT("Close"), wxDefaultPosition);
|
||||||
_connect_macro_(btn_close, VideoConfigDiag::CloseDiag, wxEVT_COMMAND_BUTTON_CLICKED, this);
|
_connect_macro_(btn_close, VideoConfigDiag::CloseDiag, wxEVT_COMMAND_BUTTON_CLICKED, this);
|
||||||
|
|
||||||
wxBoxSizer* const szr_main = new wxBoxSizer(wxVERTICAL);
|
wxBoxSizer* const szr_main = new wxBoxSizer(wxVERTICAL);
|
||||||
szr_main->Add(notebook, 1, wxEXPAND | wxALL, 5);
|
szr_main->Add(notebook, 1, wxEXPAND | wxALL, 5);
|
||||||
szr_main->Add(btn_close, 0, wxALIGN_RIGHT | wxRIGHT | wxBOTTOM, 5);
|
szr_main->Add(btn_close, 0, wxALIGN_RIGHT | wxRIGHT | wxBOTTOM, 5);
|
||||||
|
|
||||||
SetSizerAndFit(szr_main);
|
SetSizerAndFit(szr_main);
|
||||||
Center();
|
Center();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,44 +1,44 @@
|
|||||||
|
|
||||||
#ifndef _CONFIG_DIAG_H_
|
#ifndef _CONFIG_DIAG_H_
|
||||||
#define _CONFIG_DIAG_H_
|
#define _CONFIG_DIAG_H_
|
||||||
|
|
||||||
#include <wx/wx.h>
|
#include <wx/wx.h>
|
||||||
#include <wx/textctrl.h>
|
#include <wx/textctrl.h>
|
||||||
#include <wx/button.h>
|
#include <wx/button.h>
|
||||||
#include <wx/stattext.h>
|
#include <wx/stattext.h>
|
||||||
#include <wx/combobox.h>
|
#include <wx/combobox.h>
|
||||||
#include <wx/checkbox.h>
|
#include <wx/checkbox.h>
|
||||||
#include <wx/notebook.h>
|
#include <wx/notebook.h>
|
||||||
#include <wx/panel.h>
|
#include <wx/panel.h>
|
||||||
#include <wx/spinctrl.h>
|
#include <wx/spinctrl.h>
|
||||||
|
|
||||||
template <typename W>
|
template <typename W>
|
||||||
class BoolSetting : public W
|
class BoolSetting : public W
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BoolSetting(wxWindow* parent, const wxString& label, bool &setting, bool reverse = false, long style = 0);
|
BoolSetting(wxWindow* parent, const wxString& label, bool &setting, bool reverse = false, long style = 0);
|
||||||
void UpdateValue(wxCommandEvent& ev);
|
void UpdateValue(wxCommandEvent& ev);
|
||||||
private:
|
private:
|
||||||
bool &m_setting;
|
bool &m_setting;
|
||||||
const bool m_reverse;
|
const bool m_reverse;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SettingChoice : public wxChoice
|
class SettingChoice : public wxChoice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SettingChoice(wxWindow* parent, int &setting, int num = 0, const wxString choices[] = NULL);
|
SettingChoice(wxWindow* parent, int &setting, int num = 0, const wxString choices[] = NULL);
|
||||||
void UpdateValue(wxCommandEvent& ev);
|
void UpdateValue(wxCommandEvent& ev);
|
||||||
private:
|
private:
|
||||||
int &m_setting;
|
int &m_setting;
|
||||||
};
|
};
|
||||||
|
|
||||||
class VideoConfigDiag : public wxDialog
|
class VideoConfigDiag : public wxDialog
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
VideoConfigDiag(wxWindow* parent);
|
VideoConfigDiag(wxWindow* parent);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void CloseDiag(wxCommandEvent&);
|
void CloseDiag(wxCommandEvent&);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ files = [
|
|||||||
'WiimoteEmu/Attachment/Nunchuk.cpp',
|
'WiimoteEmu/Attachment/Nunchuk.cpp',
|
||||||
'WiimoteEmu/Attachment/Drums.cpp',
|
'WiimoteEmu/Attachment/Drums.cpp',
|
||||||
'WiimoteEmu/Attachment/Guitar.cpp',
|
'WiimoteEmu/Attachment/Guitar.cpp',
|
||||||
|
'WiimoteEmu/Attachment/Turntable.cpp',
|
||||||
'WiimoteEmu/EmuSubroutines.cpp',
|
'WiimoteEmu/EmuSubroutines.cpp',
|
||||||
'WiimoteEmu/Encryption.cpp',
|
'WiimoteEmu/Encryption.cpp',
|
||||||
'WiimoteEmu/Speaker.cpp',
|
'WiimoteEmu/Speaker.cpp',
|
||||||
|
|||||||
@@ -1,122 +1,122 @@
|
|||||||
#include "Turntable.h"
|
#include "Turntable.h"
|
||||||
|
|
||||||
|
|
||||||
namespace WiimoteEmu
|
namespace WiimoteEmu
|
||||||
{
|
{
|
||||||
|
|
||||||
static const u8 turntable_id[] = {0x03, 0x00, 0xa4, 0x20, 0x01, 0x03};
|
static const u8 turntable_id[] = {0x03, 0x00, 0xa4, 0x20, 0x01, 0x03};
|
||||||
|
|
||||||
static const u16 turntable_button_bitmasks[] =
|
static const u16 turntable_button_bitmasks[] =
|
||||||
{
|
{
|
||||||
Turntable::BUTTON_L_GREEN,
|
Turntable::BUTTON_L_GREEN,
|
||||||
Turntable::BUTTON_L_RED,
|
Turntable::BUTTON_L_RED,
|
||||||
Turntable::BUTTON_L_BLUE,
|
Turntable::BUTTON_L_BLUE,
|
||||||
Turntable::BUTTON_R_GREEN,
|
Turntable::BUTTON_R_GREEN,
|
||||||
Turntable::BUTTON_R_RED,
|
Turntable::BUTTON_R_RED,
|
||||||
Turntable::BUTTON_R_BLUE,
|
Turntable::BUTTON_R_BLUE,
|
||||||
Turntable::BUTTON_MINUS,
|
Turntable::BUTTON_MINUS,
|
||||||
Turntable::BUTTON_PLUS,
|
Turntable::BUTTON_PLUS,
|
||||||
Turntable::BUTTON_EUPHORIA,
|
Turntable::BUTTON_EUPHORIA,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char* const turntable_button_names[] =
|
static const char* const turntable_button_names[] =
|
||||||
{
|
{
|
||||||
"Green Left", "Red Left", "Blue Left",
|
"Green Left", "Red Left", "Blue Left",
|
||||||
"Green Right", "Red Right", "Blue Right",
|
"Green Right", "Red Right", "Blue Right",
|
||||||
"-", "+", "Euphoria",
|
"-", "+", "Euphoria",
|
||||||
};
|
};
|
||||||
|
|
||||||
Turntable::Turntable() : Attachment("Turntable")
|
Turntable::Turntable() : Attachment("Turntable")
|
||||||
{
|
{
|
||||||
// buttons
|
// buttons
|
||||||
// TODO: separate buttons into Left and Right
|
// TODO: separate buttons into Left and Right
|
||||||
groups.push_back(m_buttons = new Buttons("Buttons"));
|
groups.push_back(m_buttons = new Buttons("Buttons"));
|
||||||
for (unsigned int i = 0; i < sizeof(turntable_button_names)/sizeof(*turntable_button_names); ++i)
|
for (unsigned int i = 0; i < sizeof(turntable_button_names)/sizeof(*turntable_button_names); ++i)
|
||||||
m_buttons->controls.push_back(new ControlGroup::Input( turntable_button_names[i]));
|
m_buttons->controls.push_back(new ControlGroup::Input( turntable_button_names[i]));
|
||||||
|
|
||||||
// stick
|
// stick
|
||||||
groups.push_back(m_stick = new AnalogStick("Stick"));
|
groups.push_back(m_stick = new AnalogStick("Stick"));
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
groups.push_back(m_effect_dial = new Triggers("Effect"));
|
groups.push_back(m_effect_dial = new Triggers("Effect"));
|
||||||
m_effect_dial->controls.push_back(new ControlGroup::Input("Dial"));
|
m_effect_dial->controls.push_back(new ControlGroup::Input("Dial"));
|
||||||
|
|
||||||
//m_left_turntable
|
//m_left_turntable
|
||||||
//m_right_turntable
|
//m_right_turntable
|
||||||
//m_crossfade_slider
|
//m_crossfade_slider
|
||||||
|
|
||||||
// set up register
|
// set up register
|
||||||
// id
|
// id
|
||||||
memcpy(®[0xfa], turntable_id, sizeof(turntable_id));
|
memcpy(®[0xfa], turntable_id, sizeof(turntable_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Turntable::GetState(u8* const data, const bool focus)
|
void Turntable::GetState(u8* const data, const bool focus)
|
||||||
{
|
{
|
||||||
wm_turntable_extension* const ttdata = (wm_turntable_extension*)data;
|
wm_turntable_extension* const ttdata = (wm_turntable_extension*)data;
|
||||||
ttdata->bt = 0;
|
ttdata->bt = 0;
|
||||||
|
|
||||||
// stick
|
// stick
|
||||||
{
|
{
|
||||||
u8 x, y;
|
u8 x, y;
|
||||||
m_stick->GetState(&x, &y, 0x20, focus ? 0x1F /*0x15*/ : 0);
|
m_stick->GetState(&x, &y, 0x20, focus ? 0x1F /*0x15*/ : 0);
|
||||||
|
|
||||||
ttdata->sx = x;
|
ttdata->sx = x;
|
||||||
ttdata->sy = y;
|
ttdata->sy = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
// left table
|
// left table
|
||||||
// TODO:
|
// TODO:
|
||||||
{
|
{
|
||||||
s8 tt = 0;
|
s8 tt = 0;
|
||||||
//m_left_turntable->GetState(&tt .....);
|
//m_left_turntable->GetState(&tt .....);
|
||||||
|
|
||||||
ttdata->ltable1 = tt;
|
ttdata->ltable1 = tt;
|
||||||
ttdata->ltable2 = tt << 5;
|
ttdata->ltable2 = tt << 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
// right table
|
// right table
|
||||||
// TODO:
|
// TODO:
|
||||||
{
|
{
|
||||||
s8 tt = 0;
|
s8 tt = 0;
|
||||||
//m_right_turntable->GetState(&tt .....);
|
//m_right_turntable->GetState(&tt .....);
|
||||||
|
|
||||||
ttdata->rtable1 = tt;
|
ttdata->rtable1 = tt;
|
||||||
ttdata->rtable2 = tt << 1;
|
ttdata->rtable2 = tt << 1;
|
||||||
ttdata->rtable3 = tt << 3;
|
ttdata->rtable3 = tt << 3;
|
||||||
ttdata->rtable4 = tt << 5;
|
ttdata->rtable4 = tt << 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
// effect dial
|
// effect dial
|
||||||
{
|
{
|
||||||
u8 dial = 0;
|
u8 dial = 0;
|
||||||
m_effect_dial->GetState(&dial, focus ? 0xF : 0);
|
m_effect_dial->GetState(&dial, focus ? 0xF : 0);
|
||||||
|
|
||||||
ttdata->dial1 = dial;
|
ttdata->dial1 = dial;
|
||||||
ttdata->dial2 = dial << 3;
|
ttdata->dial2 = dial << 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// crossfade slider
|
// crossfade slider
|
||||||
// TODO:
|
// TODO:
|
||||||
{
|
{
|
||||||
u8 cfs = 0;
|
u8 cfs = 0;
|
||||||
//m_crossfade_slider->GetState(&cfs .....);
|
//m_crossfade_slider->GetState(&cfs .....);
|
||||||
|
|
||||||
ttdata->slider = cfs;
|
ttdata->slider = cfs;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (focus)
|
if (focus)
|
||||||
{
|
{
|
||||||
// buttons
|
// buttons
|
||||||
m_buttons->GetState(&ttdata->bt, turntable_button_bitmasks);
|
m_buttons->GetState(&ttdata->bt, turntable_button_bitmasks);
|
||||||
}
|
}
|
||||||
|
|
||||||
// flip button bits :/
|
// flip button bits :/
|
||||||
ttdata->bt ^= (
|
ttdata->bt ^= (
|
||||||
BUTTON_L_GREEN | BUTTON_L_RED | BUTTON_L_BLUE |
|
BUTTON_L_GREEN | BUTTON_L_RED | BUTTON_L_BLUE |
|
||||||
BUTTON_R_GREEN | BUTTON_R_RED | BUTTON_R_BLUE |
|
BUTTON_R_GREEN | BUTTON_R_RED | BUTTON_R_BLUE |
|
||||||
BUTTON_MINUS | BUTTON_PLUS | BUTTON_EUPHORIA
|
BUTTON_MINUS | BUTTON_PLUS | BUTTON_EUPHORIA
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,42 +1,42 @@
|
|||||||
#include "Attachment.h"
|
#include "Attachment.h"
|
||||||
|
|
||||||
namespace WiimoteEmu
|
namespace WiimoteEmu
|
||||||
{
|
{
|
||||||
|
|
||||||
class Turntable : public Attachment
|
class Turntable : public Attachment
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Turntable();
|
Turntable();
|
||||||
void GetState(u8* const data, const bool focus);
|
void GetState(u8* const data, const bool focus);
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
BUTTON_EUPHORIA = 0x1000,
|
BUTTON_EUPHORIA = 0x1000,
|
||||||
|
|
||||||
BUTTON_L_GREEN = 0x0800,
|
BUTTON_L_GREEN = 0x0800,
|
||||||
BUTTON_L_RED = 0x20,
|
BUTTON_L_RED = 0x20,
|
||||||
BUTTON_L_BLUE = 0x8000,
|
BUTTON_L_BLUE = 0x8000,
|
||||||
|
|
||||||
BUTTON_R_GREEN = 0x2000,
|
BUTTON_R_GREEN = 0x2000,
|
||||||
BUTTON_R_RED = 0x02,
|
BUTTON_R_RED = 0x02,
|
||||||
BUTTON_R_BLUE = 0x0400,
|
BUTTON_R_BLUE = 0x0400,
|
||||||
|
|
||||||
BUTTON_MINUS = 0x10,
|
BUTTON_MINUS = 0x10,
|
||||||
BUTTON_PLUS = 0x04,
|
BUTTON_PLUS = 0x04,
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Buttons* m_buttons;
|
Buttons* m_buttons;
|
||||||
MixedTriggers* m_triggers;
|
MixedTriggers* m_triggers;
|
||||||
AnalogStick* m_stick;
|
AnalogStick* m_stick;
|
||||||
|
|
||||||
Triggers *m_effect_dial;
|
Triggers *m_effect_dial;
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
//m_left_turntable
|
//m_left_turntable
|
||||||
//m_right_turntable
|
//m_right_turntable
|
||||||
//m_crossfade_slider
|
//m_crossfade_slider
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,95 +1,95 @@
|
|||||||
<?xml version="1.0" encoding="Windows-1252"?>
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
<VisualStudioProject
|
<VisualStudioProject
|
||||||
ProjectType="Visual C++"
|
ProjectType="Visual C++"
|
||||||
Version="9.00"
|
Version="9.00"
|
||||||
Name="ASM"
|
Name="ASM"
|
||||||
ProjectGUID="{B0723635-279A-44E0-80A6-FC21DBB7A4B4}"
|
ProjectGUID="{B0723635-279A-44E0-80A6-FC21DBB7A4B4}"
|
||||||
RootNamespace="TestSuite"
|
RootNamespace="TestSuite"
|
||||||
Keyword="MakeFileProj"
|
Keyword="MakeFileProj"
|
||||||
TargetFrameworkVersion="196613"
|
TargetFrameworkVersion="196613"
|
||||||
>
|
>
|
||||||
<Platforms>
|
<Platforms>
|
||||||
<Platform
|
<Platform
|
||||||
Name="Win32"
|
Name="Win32"
|
||||||
/>
|
/>
|
||||||
</Platforms>
|
</Platforms>
|
||||||
<ToolFiles>
|
<ToolFiles>
|
||||||
</ToolFiles>
|
</ToolFiles>
|
||||||
<Configurations>
|
<Configurations>
|
||||||
<Configuration
|
<Configuration
|
||||||
Name="Release|Win32"
|
Name="Release|Win32"
|
||||||
OutputDirectory="build"
|
OutputDirectory="build"
|
||||||
IntermediateDirectory="build"
|
IntermediateDirectory="build"
|
||||||
ConfigurationType="0"
|
ConfigurationType="0"
|
||||||
BuildLogFile="build\BuildLog.htm"
|
BuildLogFile="build\BuildLog.htm"
|
||||||
>
|
>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCNMakeTool"
|
Name="VCNMakeTool"
|
||||||
BuildCommandLine="make -r 2>&1 | sed -e 's/\(.[a-zA-Z]\+\):\([0-9]\+\):/\1(\2):/’"
|
BuildCommandLine="make -r 2>&1 | sed -e 's/\(.[a-zA-Z]\+\):\([0-9]\+\):/\1(\2):/’"
|
||||||
ReBuildCommandLine="make clean && make -r 2>&1 | sed -e 's/\(.[a-zA-Z]\+\):\([0-9]\+\):/\1(\2):/’"
|
ReBuildCommandLine="make clean && make -r 2>&1 | sed -e 's/\(.[a-zA-Z]\+\):\([0-9]\+\):/\1(\2):/’"
|
||||||
CleanCommandLine="make clean"
|
CleanCommandLine="make clean"
|
||||||
Output="dolphintest_asm.dol"
|
Output="dolphintest_asm.dol"
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG"
|
PreprocessorDefinitions="WIN32;NDEBUG"
|
||||||
IncludeSearchPath="$(ProjectDir)\include;C:\devkitPro\libogc\include"
|
IncludeSearchPath="$(ProjectDir)\include;C:\devkitPro\libogc\include"
|
||||||
ForcedIncludes=""
|
ForcedIncludes=""
|
||||||
AssemblySearchPath=""
|
AssemblySearchPath=""
|
||||||
ForcedUsingAssemblies=""
|
ForcedUsingAssemblies=""
|
||||||
CompileAsManaged=""
|
CompileAsManaged=""
|
||||||
/>
|
/>
|
||||||
</Configuration>
|
</Configuration>
|
||||||
</Configurations>
|
</Configurations>
|
||||||
<References>
|
<References>
|
||||||
</References>
|
</References>
|
||||||
<Files>
|
<Files>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\source\asm_float.cpp"
|
RelativePath=".\source\asm_float.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\source\asm_integer.cpp"
|
RelativePath=".\source\asm_integer.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\source\asm_tables.cpp"
|
RelativePath=".\source\asm_tables.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\source\asm_tables.h"
|
RelativePath=".\source\asm_tables.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\source\Defines.h"
|
RelativePath=".\source\Defines.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\source\dolphintest_asm.cpp"
|
RelativePath=".\source\dolphintest_asm.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\source\Helpers.cpp"
|
RelativePath=".\source\Helpers.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\source\Helpers.h"
|
RelativePath=".\source\Helpers.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\source\Init.cpp"
|
RelativePath=".\source\Init.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\source\Init.h"
|
RelativePath=".\source\Init.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\source\Instructions.h"
|
RelativePath=".\source\Instructions.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\Makefile"
|
RelativePath=".\Makefile"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
</Files>
|
</Files>
|
||||||
<Globals>
|
<Globals>
|
||||||
</Globals>
|
</Globals>
|
||||||
</VisualStudioProject>
|
</VisualStudioProject>
|
||||||
|
|||||||
Reference in New Issue
Block a user