Added new shader cache uids for pixel shader gen.

This commit is contained in:
NeoBrainX
2013-01-28 21:44:39 +01:00
parent 3c8df842bb
commit dc0f470215
11 changed files with 316 additions and 1169 deletions
+4 -4
View File
@@ -103,21 +103,21 @@ void GFXDebuggerBase::DumpPixelShader(const char* path)
if (!useDstAlpha)
{
output = "Destination alpha disabled:\n";
output += GeneratePixelShaderCode(DSTALPHA_NONE, g_ActiveConfig.backend_info.APIType, g_nativeVertexFmt->m_components);
/// output += GeneratePixelShaderCode(DSTALPHA_NONE, g_ActiveConfig.backend_info.APIType, g_nativeVertexFmt->m_components);
}
else
{
if(g_ActiveConfig.backend_info.bSupportsDualSourceBlend)
{
output = "Using dual source blending for destination alpha:\n";
output += GeneratePixelShaderCode(DSTALPHA_DUAL_SOURCE_BLEND, g_ActiveConfig.backend_info.APIType, g_nativeVertexFmt->m_components);
/// output += GeneratePixelShaderCode(DSTALPHA_DUAL_SOURCE_BLEND, g_ActiveConfig.backend_info.APIType, g_nativeVertexFmt->m_components);
}
else
{
output = "Using two passes for emulating destination alpha:\n";
output += GeneratePixelShaderCode(DSTALPHA_NONE, g_ActiveConfig.backend_info.APIType, g_nativeVertexFmt->m_components);
/// output += GeneratePixelShaderCode(DSTALPHA_NONE, g_ActiveConfig.backend_info.APIType, g_nativeVertexFmt->m_components);
output += "\n\nDestination alpha pass shader:\n";
output += GeneratePixelShaderCode(DSTALPHA_ALPHA_PASS, g_ActiveConfig.backend_info.APIType, g_nativeVertexFmt->m_components);
/// output += GeneratePixelShaderCode(DSTALPHA_ALPHA_PASS, g_ActiveConfig.backend_info.APIType, g_nativeVertexFmt->m_components);
}
}
File diff suppressed because it is too large Load Diff
+47 -65
View File
@@ -19,6 +19,7 @@
#define GCOGL_PIXELSHADER_H
#include "VideoCommon.h"
#include "ShaderGenCommon.h"
#define I_COLORS "color"
#define I_KCOLORS "k"
@@ -44,66 +45,6 @@
#define C_PLIGHTS (C_FOG + 3)
#define C_PMATERIALS (C_PLIGHTS + 40)
#define C_PENVCONST_END (C_PMATERIALS + 4)
#define PIXELSHADERUID_MAX_VALUES 70
#define PIXELSHADERUID_MAX_VALUES_SAFE 115
// DO NOT make anything in this class virtual.
template<bool safe>
class _PIXELSHADERUID
{
public:
u32 values[safe ? PIXELSHADERUID_MAX_VALUES_SAFE : PIXELSHADERUID_MAX_VALUES];
int num_values;
_PIXELSHADERUID()
{
}
_PIXELSHADERUID(const _PIXELSHADERUID& r)
{
num_values = r.num_values;
if (safe) memcpy(values, r.values, PIXELSHADERUID_MAX_VALUES_SAFE);
else memcpy(values, r.values, r.GetNumValues() * sizeof(values[0]));
}
int GetNumValues() const
{
if (safe) return (sizeof(values) / sizeof(u32));
else return num_values;
}
bool operator <(const _PIXELSHADERUID& _Right) const
{
int N = GetNumValues();
if (N < _Right.GetNumValues())
return true;
else if (N > _Right.GetNumValues())
return false;
for (int i = 0; i < N; ++i)
{
if (values[i] < _Right.values[i])
return true;
else if (values[i] > _Right.values[i])
return false;
}
return false;
}
bool operator ==(const _PIXELSHADERUID& _Right) const
{
int N = GetNumValues();
if (N != _Right.GetNumValues())
return false;
for (int i = 0; i < N; ++i)
{
if (values[i] != _Right.values[i])
return false;
}
return true;
}
};
typedef _PIXELSHADERUID<false> PIXELSHADERUID;
typedef _PIXELSHADERUID<true> PIXELSHADERUIDSAFE;
// Different ways to achieve rendering with destination alpha
enum DSTALPHA_MODE
@@ -113,12 +54,53 @@ enum DSTALPHA_MODE
DSTALPHA_DUAL_SOURCE_BLEND // Use dual-source blending
};
const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components);
enum ALPHA_PRETEST_RESULT
{
ALPHAPT_UNDEFINED, // AlphaTest Result is not defined
ALPHAPT_ALWAYSFAIL, // Alpha test alway Fail
ALPHAPT_ALWAYSPASS // Alpha test alway Pass
};
void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode, u32 components);
void GetSafePixelShaderId(PIXELSHADERUIDSAFE *uid, DSTALPHA_MODE dstAlphaMode, u32 components);
struct pixel_shader_uid_data
{
u32 components;
DSTALPHA_MODE dstAlphaMode; // TODO: as u32 :2
ALPHA_PRETEST_RESULT Pretest; // TODO: As :2
u32 nIndirectStagesUsed : 8;
struct {
u32 numtexgens : 4;
u32 numtevstages : 4;
u32 numindstages : 3;
} genMode;
u32 fogc_proj_fselfsel : 3;
struct
{
u32 unknown : 1;
u32 projection : 1; // XF_TEXPROJ_X
u32 inputform : 2; // XF_TEXINPUT_X
u32 texgentype : 3; // XF_TEXGEN_X
u32 sourcerow : 5; // XF_SRCGEOM_X
u32 embosssourceshift : 3; // what generated texcoord to use
u32 embosslightshift : 3; // light index that is used
} texMtxInfo[8];
struct
{
u32 bi0 : 3; // indirect tex stage 0 ntexmap
u32 bc0 : 3; // indirect tex stage 0 ntexcoord
u32 bi1 : 3;
u32 bc1 : 3;
u32 bi2 : 3;
u32 bc3 : 3;
u32 bi4 : 3;
u32 bc4 : 3;
} tevindref;
};
// Used to make sure that our optimized pixel shader IDs don't lose any possible shader code changes
void ValidatePixelShaderIDs(API_TYPE api, PIXELSHADERUIDSAFE old_id, const std::string& old_code, DSTALPHA_MODE dstAlphaMode, u32 components);
typedef ShaderUid<pixel_shader_uid_data> PixelShaderUid;
typedef ShaderCode<pixel_shader_uid_data> PixelShaderCode;
void GeneratePixelShaderCode(PixelShaderCode& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components);
void GetPixelShaderId(PixelShaderUid& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components);
#endif // GCOGL_PIXELSHADER_H
@@ -44,7 +44,7 @@ public:
// TODO: Store last frame used and order by that? makes much more sense anyway...
bool operator < (const ShaderUid& obj) const
{
for (int i = 0; i < sizeof(uid_data) / sizeof(u32); ++i)
for (unsigned int i = 0; i < sizeof(uid_data) / sizeof(u32); ++i)
{
if (this->values[i] < obj.values[i])
return true;
@@ -91,4 +91,10 @@ private:
char* write_ptr;
};
enum GenOutput
{
GO_ShaderCode,
GO_ShaderUid,
};
#endif // _SHADERGENCOMMON_H
@@ -28,11 +28,6 @@
static char text[16768];
enum GenOutput
{
GO_ShaderCode,
GO_ShaderUid,
};
// TODO: Check if something goes wrong if the cached shaders used pixel lighting but it's disabled later??
template<class T>
void GenerateVSOutputStruct(T& object, u32 components, API_TYPE api_type)
File diff suppressed because it is too large Load Diff
@@ -51,7 +51,7 @@
#define C_VENVCONST_END (C_DEPTHPARAMS + 4)
// TODO: Need packing?
struct uid_data
struct vertex_shader_uid_data
{
u32 components;
u32 numColorChans : 2;
@@ -82,8 +82,8 @@ struct uid_data
} lit_chans[4];
};
typedef ShaderUid<uid_data> VertexShaderUid;
typedef ShaderCode<uid_data> VertexShaderCode;
typedef ShaderUid<vertex_shader_uid_data> VertexShaderUid;
typedef ShaderCode<vertex_shader_uid_data> VertexShaderCode;
void GetVertexShaderUid(VertexShaderUid& object, u32 components, API_TYPE api_type);
void GenerateVertexShaderCode(VertexShaderCode& object, u32 components, API_TYPE api_type);
@@ -82,7 +82,7 @@ struct uid_data
} lit_chans[4];
};
typedef ShaderUid<uid_data, 24> VertexShaderUid;
typedef ShaderUid<uid_data> VertexShaderUid;
typedef ShaderCode<uid_data> VertexShaderCode;
void GetVertexShaderUid(VertexShaderUid& object, u32 components, API_TYPE api_type);
+1 -1
View File
@@ -144,7 +144,7 @@ struct VideoConfig
int iAdapter;
// Debugging
bool bEnableShaderDebugging;
bool bEnableShaderDebugging; // TODO: Obsolete?
// Static config per API
// TODO: Move this out of VideoConfig
@@ -39,13 +39,13 @@ static int s_nMaxPixelInstructions;
static GLuint s_ColorMatrixProgram = 0;
static GLuint s_DepthMatrixProgram = 0;
PixelShaderCache::PSCache PixelShaderCache::PixelShaders;
PIXELSHADERUID PixelShaderCache::s_curuid;
PixelShaderUid PixelShaderCache::s_curuid;
bool PixelShaderCache::s_displayCompileAlert;
GLuint PixelShaderCache::CurrentShader;
bool PixelShaderCache::ShaderEnabled;
PixelShaderCache::PSCacheEntry* PixelShaderCache::last_entry = NULL;
PIXELSHADERUID PixelShaderCache::last_uid;
PixelShaderUid PixelShaderCache::last_uid;
GLuint PixelShaderCache::GetDepthMatrixProgram()
{
@@ -183,16 +183,15 @@ void PixelShaderCache::Shutdown()
FRAGMENTSHADER* PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components)
{
PIXELSHADERUID uid;
GetPixelShaderId(&uid, dstAlphaMode, components);
PixelShaderUid uid;
GetPixelShaderId(uid, dstAlphaMode, API_OPENGL, components);
// Check if the shader is already set
if (last_entry)
{
if (uid == last_uid)
{
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
ValidatePixelShaderIDs(API_OPENGL, last_entry->safe_uid, last_entry->shader.strprog, dstAlphaMode, components);
return &last_entry->shader;
}
}
@@ -206,19 +205,18 @@ FRAGMENTSHADER* PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 comp
last_entry = &entry;
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
ValidatePixelShaderIDs(API_OPENGL, entry.safe_uid, entry.shader.strprog, dstAlphaMode, components);
return &last_entry->shader;
}
// Make an entry in the table
PSCacheEntry& newentry = PixelShaders[uid];
last_entry = &newentry;
const char *code = GeneratePixelShaderCode(dstAlphaMode, API_OPENGL, components);
PixelShaderCode code;
GeneratePixelShaderCode(code, dstAlphaMode, API_OPENGL, components);
if (g_ActiveConfig.bEnableShaderDebugging && code)
if (g_ActiveConfig.bEnableShaderDebugging)
{
GetSafePixelShaderId(&newentry.safe_uid, dstAlphaMode, components);
newentry.shader.strprog = code;
newentry.shader.strprog = code.GetBuffer();
}
#if defined(_DEBUG) || defined(DEBUGFAST)
@@ -227,11 +225,11 @@ FRAGMENTSHADER* PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 comp
char szTemp[MAX_PATH];
sprintf(szTemp, "%sps_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), counter++);
SaveData(szTemp, code);
SaveData(szTemp, code.GetBuffer()); /// XXX
}
#endif
if (!code || !CompilePixelShader(newentry.shader, code)) {
if (!code.GetBuffer() || !CompilePixelShader(newentry.shader, code.GetBuffer())) {
GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true);
return NULL;
}
@@ -53,20 +53,19 @@ class PixelShaderCache
{
shader.Destroy();
}
PIXELSHADERUIDSAFE safe_uid;
};
typedef std::map<PIXELSHADERUID, PSCacheEntry> PSCache;
typedef std::map<PixelShaderUid, PSCacheEntry> PSCache;
static PSCache PixelShaders;
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 GLuint CurrentShader;
static PSCacheEntry* last_entry;
static PIXELSHADERUID last_uid;
static PixelShaderUid last_uid;
static bool ShaderEnabled;