mirror of
https://github.com/izzy2lost/dolphin.git
synced 2026-06-19 01:16:48 -07:00
Merge branch 'master' of https://code.google.com/p/dolphin-emu
This commit is contained in:
@@ -21,12 +21,10 @@
|
||||
#include "Common.h"
|
||||
#include <fstream>
|
||||
|
||||
// Update this to the current SVN revision every time you change shader generation code.
|
||||
// We don't automatically get this from SVN_REV because that would mean regenerating the
|
||||
// shader cache for every revision, graphics-related or not, which is simply annoying.
|
||||
// Increment this every time you change shader generation code.
|
||||
enum
|
||||
{
|
||||
LINEAR_DISKCACHE_VER = 6964
|
||||
LINEAR_DISKCACHE_VER = 6967
|
||||
};
|
||||
|
||||
// On disk format:
|
||||
|
||||
@@ -86,7 +86,7 @@ bool MsgAlert(bool yes_no, int Style, const char* format, ...)
|
||||
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
CharArrayFromFormatV(buffer, 2047, str_translator(format).c_str(), args);
|
||||
CharArrayFromFormatV(buffer, sizeof(buffer)-1, str_translator(format).c_str(), args);
|
||||
va_end(args);
|
||||
|
||||
ERROR_LOG(MASTER_LOG, "%s: %s", caption.c_str(), buffer);
|
||||
|
||||
@@ -21,6 +21,21 @@
|
||||
|
||||
#define WRITE p+=sprintf
|
||||
|
||||
int GetLightingShaderId(u32* out)
|
||||
{
|
||||
for (int i = 0; i < xfregs.numChan.numColorChans; ++i)
|
||||
{
|
||||
out[i] = xfregs.color[i].enablelighting ?
|
||||
(u32)xfregs.color[i].hex :
|
||||
(u32)xfregs.color[i].matsource;
|
||||
out[i] |= (xfregs.alpha[i].enablelighting ?
|
||||
(u32)xfregs.alpha[i].hex :
|
||||
(u32)xfregs.alpha[i].matsource) << 15;
|
||||
}
|
||||
_assert_(xfregs.numChan.numColorChans <= 2);
|
||||
return xfregs.numChan.numColorChans;
|
||||
}
|
||||
|
||||
// coloralpha - 1 if color, 2 if alpha
|
||||
char *GenerateLightShader(char *p, int index, const LitChannel& chan, const char* lightsName, int coloralpha)
|
||||
{
|
||||
|
||||
@@ -18,6 +18,9 @@
|
||||
#ifndef _LIGHTINGSHADERGEN_H_
|
||||
#define _LIGHTINGSHADERGEN_H_
|
||||
|
||||
#include "CommonTypes.h"
|
||||
|
||||
int GetLightingShaderId(u32* out);
|
||||
char *GenerateLightingShader(char *p, int components, const char* materialsName, const char* lightsName, const char* inColorName, const char* dest);
|
||||
|
||||
#endif // _LIGHTINGSHADERGEN_H_
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -44,44 +44,42 @@
|
||||
#define C_PLIGHTS (C_FOG + 3)
|
||||
#define C_PMATERIALS (C_PLIGHTS + 40)
|
||||
#define C_PENVCONST_END (C_PMATERIALS + 4)
|
||||
#define PIXELSHADERUID_MAX_VALUES (5 + 32 + 6 + 11 + 2)
|
||||
#define PIXELSHADERUID_MAX_VALUES 70
|
||||
#define PIXELSHADERUID_MAX_VALUES_SAFE 120
|
||||
|
||||
// DO NOT make anything in this class virtual.
|
||||
class PIXELSHADERUID
|
||||
template<bool safe>
|
||||
class _PIXELSHADERUID
|
||||
{
|
||||
public:
|
||||
u32 values[PIXELSHADERUID_MAX_VALUES];
|
||||
u16 tevstages, indstages;
|
||||
u32 values[safe ? PIXELSHADERUID_MAX_VALUES_SAFE : PIXELSHADERUID_MAX_VALUES];
|
||||
int num_values;
|
||||
|
||||
PIXELSHADERUID()
|
||||
_PIXELSHADERUID()
|
||||
{
|
||||
memset(values, 0, PIXELSHADERUID_MAX_VALUES * 4);
|
||||
tevstages = indstages = 0;
|
||||
}
|
||||
|
||||
PIXELSHADERUID(const PIXELSHADERUID& r)
|
||||
_PIXELSHADERUID(const _PIXELSHADERUID& r)
|
||||
{
|
||||
tevstages = r.tevstages;
|
||||
indstages = r.indstages;
|
||||
int N = GetNumValues();
|
||||
_assert_(N <= PIXELSHADERUID_MAX_VALUES);
|
||||
for (int i = 0; i < N; ++i)
|
||||
values[i] = r.values[i];
|
||||
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
|
||||
{
|
||||
return tevstages + indstages + 4;
|
||||
if (safe) return (sizeof(values) / sizeof(u32));
|
||||
else return num_values;
|
||||
}
|
||||
|
||||
bool operator <(const PIXELSHADERUID& _Right) const
|
||||
bool operator <(const _PIXELSHADERUID& _Right) const
|
||||
{
|
||||
if (values[0] < _Right.values[0])
|
||||
return true;
|
||||
else if (values[0] > _Right.values[0])
|
||||
return false;
|
||||
int N = GetNumValues();
|
||||
for (int i = 1; i < N; ++i)
|
||||
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;
|
||||
@@ -91,12 +89,12 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator ==(const PIXELSHADERUID& _Right) const
|
||||
bool operator ==(const _PIXELSHADERUID& _Right) const
|
||||
{
|
||||
if (values[0] != _Right.values[0])
|
||||
return false;
|
||||
int N = GetNumValues();
|
||||
for (int i = 1; i < N; ++i)
|
||||
if (N != _Right.GetNumValues())
|
||||
return false;
|
||||
for (int i = 0; i < N; ++i)
|
||||
{
|
||||
if (values[i] != _Right.values[i])
|
||||
return false;
|
||||
@@ -104,6 +102,8 @@ public:
|
||||
return true;
|
||||
}
|
||||
};
|
||||
typedef _PIXELSHADERUID<false> PIXELSHADERUID;
|
||||
typedef _PIXELSHADERUID<true> PIXELSHADERUIDSAFE;
|
||||
|
||||
// Different ways to achieve rendering with destination alpha
|
||||
enum DSTALPHA_MODE
|
||||
@@ -114,8 +114,11 @@ enum DSTALPHA_MODE
|
||||
};
|
||||
|
||||
const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components);
|
||||
void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode);
|
||||
|
||||
extern PIXELSHADERUID last_pixel_shader_uid;
|
||||
void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode, u32 components);
|
||||
void GetSafePixelShaderId(PIXELSHADERUIDSAFE *uid, DSTALPHA_MODE dstAlphaMode, u32 components);
|
||||
|
||||
// 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);
|
||||
|
||||
#endif // GCOGL_PIXELSHADER_H
|
||||
|
||||
@@ -26,25 +26,19 @@
|
||||
#include "VertexShaderGen.h"
|
||||
#include "VideoConfig.h"
|
||||
|
||||
VERTEXSHADERUID last_vertex_shader_uid;
|
||||
|
||||
// Mash together all the inputs that contribute to the code of a generated vertex shader into
|
||||
// a unique identifier, basically containing all the bits. Yup, it's a lot ....
|
||||
void GetVertexShaderId(VERTEXSHADERUID *uid, u32 components)
|
||||
{
|
||||
memset(uid->values, 0, sizeof(uid->values));
|
||||
uid->values[0] = components |
|
||||
(xfregs.numTexGen.numTexGens << 23) |
|
||||
(xfregs.numChan.numColorChans << 27) |
|
||||
(xfregs.dualTexTrans.enabled << 29);
|
||||
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
uid->values[1+i] = xfregs.color[i].enablelighting ?
|
||||
(u32)xfregs.color[i].hex :
|
||||
(u32)xfregs.color[i].matsource;
|
||||
uid->values[1+i] |= (xfregs.alpha[i].enablelighting ?
|
||||
(u32)xfregs.alpha[i].hex :
|
||||
(u32)xfregs.alpha[i].matsource) << 15;
|
||||
}
|
||||
// TODO: If pixel lighting is enabled, do we even have to bother about storing lighting related registers here?
|
||||
GetLightingShaderId(&uid->values[1]);
|
||||
|
||||
uid->values[2] |= (g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) << 31;
|
||||
u32 *pcurvalue = &uid->values[3];
|
||||
for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i) {
|
||||
@@ -69,6 +63,69 @@ void GetVertexShaderId(VERTEXSHADERUID *uid, u32 components)
|
||||
}
|
||||
}
|
||||
|
||||
void GetSafeVertexShaderId(VERTEXSHADERUIDSAFE *uid, u32 components)
|
||||
{
|
||||
// Just store all used registers here without caring whether we need all bits or less.
|
||||
memset(uid->values, 0, sizeof(uid->values));
|
||||
u32* ptr = uid->values;
|
||||
*ptr++ = components;
|
||||
*ptr++ = xfregs.numTexGen.hex;
|
||||
*ptr++ = xfregs.numChan.hex;
|
||||
*ptr++ = xfregs.dualTexTrans.hex;
|
||||
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
*ptr++ = xfregs.color[i].hex;
|
||||
*ptr++ = xfregs.alpha[i].hex;
|
||||
}
|
||||
*ptr++ = g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting;
|
||||
for (unsigned int i = 0; i < 8; ++i) {
|
||||
*ptr++ = xfregs.texMtxInfo[i].hex;
|
||||
*ptr++ = xfregs.postMtxInfo[i].hex;
|
||||
}
|
||||
_assert_((ptr - uid->values) == uid->GetNumValues());
|
||||
}
|
||||
|
||||
|
||||
void ValidateVertexShaderIDs(API_TYPE api, VERTEXSHADERUIDSAFE old_id, const std::string& old_code, u32 components)
|
||||
{
|
||||
if (!g_ActiveConfig.bEnableShaderDebugging)
|
||||
return;
|
||||
|
||||
VERTEXSHADERUIDSAFE new_id;
|
||||
GetSafeVertexShaderId(&new_id, components);
|
||||
|
||||
if (!(old_id == new_id))
|
||||
{
|
||||
std::string new_code(GenerateVertexShaderCode(components, api));
|
||||
if (old_code != new_code)
|
||||
{
|
||||
_assert_(old_id.GetNumValues() == new_id.GetNumValues());
|
||||
|
||||
char msg[8192];
|
||||
char* ptr = msg;
|
||||
ptr += sprintf(ptr, "Vertex shader IDs matched but unique IDs did not!\nUnique IDs (old <-> new):\n");
|
||||
const int N = new_id.GetNumValues();
|
||||
for (int i = 0; i < N/2; ++i)
|
||||
ptr += sprintf(ptr, "%02d, %08X %08X | %08X %08X\n", 2*i, old_id.values[2*i], old_id.values[2*i+1],
|
||||
new_id.values[2*i], new_id.values[2*i+1]);
|
||||
if (N % 2)
|
||||
ptr += sprintf(ptr, "%02d, %08X | %08X\n", N-1, old_id.values[N-1], new_id.values[N-1]);
|
||||
|
||||
static int num_failures = 0;
|
||||
char szTemp[MAX_PATH];
|
||||
sprintf(szTemp, "%svsuid_mismatch_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), num_failures++);
|
||||
std::ofstream file(szTemp);
|
||||
file << msg;
|
||||
file << "\n\nOld shader code:\n" << old_code;
|
||||
file << "\n\nNew shader code:\n" << new_code;
|
||||
file.close();
|
||||
|
||||
PanicAlert("Unique pixel shader ID mismatch!\n\nReport this to the devs, along with the contents of %s.", szTemp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static char text[16384];
|
||||
|
||||
#define WRITE p+=sprintf
|
||||
@@ -244,7 +301,8 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type)
|
||||
else
|
||||
WRITE(p, "o.colors_0 = float4(1.0f, 1.0f, 1.0f, 1.0f);\n");
|
||||
}
|
||||
|
||||
|
||||
// TODO: This probably isn't necessary if pixel lighting is enabled.
|
||||
p = GenerateLightingShader(p, components, I_MATERIALS, I_LIGHTS, "color", "o.colors_");
|
||||
|
||||
if(xfregs.numChan.numColorChans < 2)
|
||||
|
||||
@@ -48,17 +48,18 @@
|
||||
#define C_DEPTHPARAMS (C_POSTTRANSFORMMATRICES + 64)
|
||||
#define C_VENVCONST_END (C_DEPTHPARAMS + 4)
|
||||
|
||||
class VERTEXSHADERUID
|
||||
template<bool safe>
|
||||
class _VERTEXSHADERUID
|
||||
{
|
||||
#define NUM_VSUID_VALUES_SAFE 25
|
||||
public:
|
||||
u32 values[9];
|
||||
u32 values[safe ? NUM_VSUID_VALUES_SAFE : 9];
|
||||
|
||||
VERTEXSHADERUID()
|
||||
_VERTEXSHADERUID()
|
||||
{
|
||||
memset(values, 0, sizeof(values));
|
||||
}
|
||||
|
||||
VERTEXSHADERUID(const VERTEXSHADERUID& r)
|
||||
_VERTEXSHADERUID(const _VERTEXSHADERUID& r)
|
||||
{
|
||||
for (size_t i = 0; i < sizeof(values) / sizeof(u32); ++i)
|
||||
values[i] = r.values[i];
|
||||
@@ -66,10 +67,11 @@ public:
|
||||
|
||||
int GetNumValues() const
|
||||
{
|
||||
return (((values[0] >> 23) & 0xf) * 3 + 3) / 4 + 3; // numTexGens*3/4+1
|
||||
if (safe) return NUM_VSUID_VALUES_SAFE;
|
||||
else return (((values[0] >> 23) & 0xf) * 3 + 3) / 4 + 3; // numTexGens*3/4+1
|
||||
}
|
||||
|
||||
bool operator <(const VERTEXSHADERUID& _Right) const
|
||||
bool operator <(const _VERTEXSHADERUID& _Right) const
|
||||
{
|
||||
if (values[0] < _Right.values[0])
|
||||
return true;
|
||||
@@ -86,7 +88,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator ==(const VERTEXSHADERUID& _Right) const
|
||||
bool operator ==(const _VERTEXSHADERUID& _Right) const
|
||||
{
|
||||
if (values[0] != _Right.values[0])
|
||||
return false;
|
||||
@@ -99,14 +101,18 @@ public:
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
typedef _VERTEXSHADERUID<false> VERTEXSHADERUID;
|
||||
typedef _VERTEXSHADERUID<true> VERTEXSHADERUIDSAFE;
|
||||
|
||||
|
||||
// components is included in the uid.
|
||||
char* GenerateVSOutputStruct(char* p, u32 components, API_TYPE api_type);
|
||||
const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type);
|
||||
void GetVertexShaderId(VERTEXSHADERUID *uid, u32 components);
|
||||
|
||||
extern VERTEXSHADERUID last_vertex_shader_uid;
|
||||
void GetVertexShaderId(VERTEXSHADERUID *uid, u32 components);
|
||||
void GetSafeVertexShaderId(VERTEXSHADERUIDSAFE *uid, u32 components);
|
||||
|
||||
// Used to make sure that our optimized vertex shader IDs don't lose any possible shader code changes
|
||||
void ValidateVertexShaderIDs(API_TYPE api, VERTEXSHADERUIDSAFE old_id, const std::string& old_code, u32 components);
|
||||
|
||||
#endif // GCOGL_VERTEXSHADER_H
|
||||
|
||||
@@ -96,6 +96,8 @@ void VideoConfig::Load(const char *ini_file)
|
||||
iniFile.Get("Settings", "EnableOpenCL", &bEnableOpenCL, false);
|
||||
iniFile.Get("Settings", "OMPDecoder", &bOMPDecoder, false);
|
||||
|
||||
iniFile.Get("Settings", "EnableShaderDebugging", &bEnableShaderDebugging, false);
|
||||
|
||||
iniFile.Get("Enhancements", "ForceFiltering", &bForceFiltering, 0);
|
||||
iniFile.Get("Enhancements", "MaxAnisotropy", &iMaxAnisotropy, 0); // NOTE - this is x in (1 << x)
|
||||
iniFile.Get("Enhancements", "PostProcessingShader", &sPostProcessingShader, "");
|
||||
@@ -231,6 +233,8 @@ void VideoConfig::Save(const char *ini_file)
|
||||
iniFile.Set("Settings", "EnableOpenCL", bEnableOpenCL);
|
||||
iniFile.Set("Settings", "OMPDecoder", bOMPDecoder);
|
||||
|
||||
iniFile.Set("Settings", "EnableShaderDebugging", bEnableShaderDebugging);
|
||||
|
||||
iniFile.Set("Enhancements", "ForceFiltering", bForceFiltering);
|
||||
iniFile.Set("Enhancements", "MaxAnisotropy", iMaxAnisotropy);
|
||||
iniFile.Set("Enhancements", "PostProcessingShader", sPostProcessingShader);
|
||||
|
||||
@@ -147,6 +147,9 @@ struct VideoConfig
|
||||
// D3D only config, mostly to be merged into the above
|
||||
int iAdapter;
|
||||
|
||||
// Debugging
|
||||
bool bEnableShaderDebugging;
|
||||
|
||||
// Static config per API
|
||||
// TODO: Move this out of VideoConfig
|
||||
struct
|
||||
|
||||
@@ -41,6 +41,7 @@ namespace DX11
|
||||
|
||||
PixelShaderCache::PSCache PixelShaderCache::PixelShaders;
|
||||
const PixelShaderCache::PSCacheEntry* PixelShaderCache::last_entry;
|
||||
PIXELSHADERUID PixelShaderCache::last_uid;
|
||||
|
||||
LinearDiskCache<PIXELSHADERUID, u8> g_ps_disk_cache;
|
||||
|
||||
@@ -412,6 +413,11 @@ void PixelShaderCache::Init()
|
||||
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());
|
||||
PixelShaderCacheInserter inserter;
|
||||
g_ps_disk_cache.OpenAndRead(cache_filename, inserter);
|
||||
|
||||
if (g_Config.bEnableShaderDebugging)
|
||||
Clear();
|
||||
|
||||
last_entry = NULL;
|
||||
}
|
||||
|
||||
// ONLY to be used during shutdown.
|
||||
@@ -420,6 +426,8 @@ void PixelShaderCache::Clear()
|
||||
for (PSCache::iterator iter = PixelShaders.begin(); iter != PixelShaders.end(); iter++)
|
||||
iter->second.Destroy();
|
||||
PixelShaders.clear();
|
||||
|
||||
last_entry = NULL;
|
||||
}
|
||||
|
||||
// Used in Swap() when AA mode has changed
|
||||
@@ -454,28 +462,31 @@ void PixelShaderCache::Shutdown()
|
||||
bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components)
|
||||
{
|
||||
PIXELSHADERUID uid;
|
||||
GetPixelShaderId(&uid, dstAlphaMode);
|
||||
GetPixelShaderId(&uid, dstAlphaMode, components);
|
||||
|
||||
// Check if the shader is already set
|
||||
if (uid == last_pixel_shader_uid && PixelShaders[uid].frameCount == frameCount)
|
||||
if (last_entry)
|
||||
{
|
||||
PSCache::const_iterator iter = PixelShaders.find(uid);
|
||||
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE,true);
|
||||
return (iter != PixelShaders.end() && iter->second.shader);
|
||||
if (uid == last_uid)
|
||||
{
|
||||
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE,true);
|
||||
ValidatePixelShaderIDs(API_D3D11, last_entry->safe_uid, last_entry->code, dstAlphaMode, components);
|
||||
return (last_entry->shader != NULL);
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(&last_pixel_shader_uid, &uid, sizeof(PIXELSHADERUID));
|
||||
last_uid = uid;
|
||||
|
||||
// Check if the shader is already in the cache
|
||||
PSCache::iterator iter;
|
||||
iter = PixelShaders.find(uid);
|
||||
if (iter != PixelShaders.end())
|
||||
{
|
||||
iter->second.frameCount = frameCount;
|
||||
const PSCacheEntry &entry = iter->second;
|
||||
last_entry = &entry;
|
||||
|
||||
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE,true);
|
||||
ValidatePixelShaderIDs(API_D3D11, entry.safe_uid, entry.code, dstAlphaMode, components);
|
||||
return (entry.shader != NULL);
|
||||
}
|
||||
|
||||
@@ -491,12 +502,18 @@ bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components)
|
||||
|
||||
// Insert the bytecode into the caches
|
||||
g_ps_disk_cache.Append(uid, pbytecode->Data(), pbytecode->Size());
|
||||
g_ps_disk_cache.Sync();
|
||||
|
||||
bool result = InsertByteCode(uid, pbytecode->Data(), pbytecode->Size());
|
||||
bool success = InsertByteCode(uid, pbytecode->Data(), pbytecode->Size());
|
||||
pbytecode->Release();
|
||||
|
||||
if (g_ActiveConfig.bEnableShaderDebugging && success)
|
||||
{
|
||||
PixelShaders[uid].code = code;
|
||||
GetSafePixelShaderId(&PixelShaders[uid].safe_uid, dstAlphaMode, components);
|
||||
}
|
||||
|
||||
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
|
||||
return result;
|
||||
return success;
|
||||
}
|
||||
|
||||
bool PixelShaderCache::InsertByteCode(const PIXELSHADERUID &uid, const void* bytecode, unsigned int bytecodelen)
|
||||
@@ -511,7 +528,6 @@ bool PixelShaderCache::InsertByteCode(const PIXELSHADERUID &uid, const void* byt
|
||||
// Make an entry in the table
|
||||
PSCacheEntry newentry;
|
||||
newentry.shader = shader;
|
||||
newentry.frameCount = frameCount;
|
||||
PixelShaders[uid] = newentry;
|
||||
last_entry = &PixelShaders[uid];
|
||||
|
||||
|
||||
@@ -17,11 +17,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include "PixelShaderGen.h"
|
||||
|
||||
#include <d3d11.h>
|
||||
|
||||
class PIXELSHADERUID;
|
||||
#include <map>
|
||||
|
||||
enum DSTALPHA_MODE;
|
||||
|
||||
namespace DX11
|
||||
@@ -52,9 +53,11 @@ private:
|
||||
struct PSCacheEntry
|
||||
{
|
||||
ID3D11PixelShader* shader;
|
||||
int frameCount;
|
||||
|
||||
PSCacheEntry() : shader(NULL), frameCount(0) {}
|
||||
PIXELSHADERUIDSAFE safe_uid;
|
||||
std::string code;
|
||||
|
||||
PSCacheEntry() : shader(NULL) {}
|
||||
void Destroy() { SAFE_RELEASE(shader); }
|
||||
};
|
||||
|
||||
@@ -62,6 +65,7 @@ private:
|
||||
|
||||
static PSCache PixelShaders;
|
||||
static const PSCacheEntry* last_entry;
|
||||
static PIXELSHADERUID last_uid;
|
||||
};
|
||||
|
||||
} // namespace DX11
|
||||
|
||||
@@ -37,6 +37,7 @@ namespace DX11 {
|
||||
|
||||
VertexShaderCache::VSCache VertexShaderCache::vshaders;
|
||||
const VertexShaderCache::VSCacheEntry *VertexShaderCache::last_entry;
|
||||
VERTEXSHADERUID VertexShaderCache::last_uid;
|
||||
|
||||
static ID3D11VertexShader* SimpleVertexShader = NULL;
|
||||
static ID3D11VertexShader* ClearVertexShader = NULL;
|
||||
@@ -174,6 +175,11 @@ void VertexShaderCache::Init()
|
||||
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());
|
||||
VertexShaderCacheInserter inserter;
|
||||
g_vs_disk_cache.OpenAndRead(cache_filename, inserter);
|
||||
|
||||
if (g_Config.bEnableShaderDebugging)
|
||||
Clear();
|
||||
|
||||
last_entry = NULL;
|
||||
}
|
||||
|
||||
void VertexShaderCache::Clear()
|
||||
@@ -181,6 +187,8 @@ void VertexShaderCache::Clear()
|
||||
for (VSCache::iterator iter = vshaders.begin(); iter != vshaders.end(); ++iter)
|
||||
iter->second.Destroy();
|
||||
vshaders.clear();
|
||||
|
||||
last_entry = NULL;
|
||||
}
|
||||
|
||||
void VertexShaderCache::Shutdown()
|
||||
@@ -202,22 +210,26 @@ bool VertexShaderCache::SetShader(u32 components)
|
||||
{
|
||||
VERTEXSHADERUID uid;
|
||||
GetVertexShaderId(&uid, components);
|
||||
if (uid == last_vertex_shader_uid && vshaders[uid].frameCount == frameCount)
|
||||
if (last_entry)
|
||||
{
|
||||
GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true);
|
||||
return (vshaders[uid].shader != NULL);
|
||||
if (uid == last_uid)
|
||||
{
|
||||
GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true);
|
||||
ValidateVertexShaderIDs(API_D3D11, last_entry->safe_uid, last_entry->code, components);
|
||||
return (last_entry->shader != NULL);
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(&last_vertex_shader_uid, &uid, sizeof(VERTEXSHADERUID));
|
||||
last_uid = uid;
|
||||
|
||||
VSCache::iterator iter = vshaders.find(uid);
|
||||
if (iter != vshaders.end())
|
||||
{
|
||||
iter->second.frameCount = frameCount;
|
||||
const VSCacheEntry &entry = iter->second;
|
||||
last_entry = &entry;
|
||||
|
||||
GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true);
|
||||
ValidateVertexShaderIDs(API_D3D11, entry.safe_uid, entry.code, components);
|
||||
return (entry.shader != NULL);
|
||||
}
|
||||
|
||||
@@ -232,12 +244,18 @@ bool VertexShaderCache::SetShader(u32 components)
|
||||
return false;
|
||||
}
|
||||
g_vs_disk_cache.Append(uid, pbytecode->Data(), pbytecode->Size());
|
||||
g_vs_disk_cache.Sync();
|
||||
|
||||
bool result = InsertByteCode(uid, pbytecode);
|
||||
bool success = InsertByteCode(uid, pbytecode);
|
||||
pbytecode->Release();
|
||||
|
||||
if (g_ActiveConfig.bEnableShaderDebugging && success)
|
||||
{
|
||||
vshaders[uid].code = code;
|
||||
GetSafeVertexShaderId(&vshaders[uid].safe_uid, components);
|
||||
}
|
||||
|
||||
GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true);
|
||||
return result;
|
||||
return success;
|
||||
}
|
||||
|
||||
bool VertexShaderCache::InsertByteCode(const VERTEXSHADERUID &uid, D3DBlob* bcodeblob)
|
||||
@@ -252,7 +270,6 @@ bool VertexShaderCache::InsertByteCode(const VERTEXSHADERUID &uid, D3DBlob* bcod
|
||||
// Make an entry in the table
|
||||
VSCacheEntry entry;
|
||||
entry.shader = shader;
|
||||
entry.frameCount = frameCount;
|
||||
entry.SetByteCode(bcodeblob);
|
||||
|
||||
vshaders[uid] = entry;
|
||||
|
||||
@@ -18,12 +18,12 @@
|
||||
#ifndef _VERTEXSHADERCACHE_H
|
||||
#define _VERTEXSHADERCACHE_H
|
||||
|
||||
#include <map>
|
||||
#include "VertexShaderGen.h"
|
||||
|
||||
#include "D3DBase.h"
|
||||
#include "D3DBlob.h"
|
||||
|
||||
class VERTEXSHADERUID;
|
||||
#include <map>
|
||||
|
||||
namespace DX11 {
|
||||
|
||||
@@ -51,9 +51,11 @@ private:
|
||||
{
|
||||
ID3D11VertexShader* shader;
|
||||
D3DBlob* bytecode; // needed to initialize the input layout
|
||||
int frameCount;
|
||||
|
||||
VSCacheEntry() : shader(NULL), bytecode(NULL), frameCount(0) {}
|
||||
VERTEXSHADERUIDSAFE safe_uid;
|
||||
std::string code;
|
||||
|
||||
VSCacheEntry() : shader(NULL), bytecode(NULL) {}
|
||||
void SetByteCode(D3DBlob* blob)
|
||||
{
|
||||
SAFE_RELEASE(bytecode);
|
||||
@@ -70,6 +72,7 @@ private:
|
||||
|
||||
static VSCache vshaders;
|
||||
static const VSCacheEntry* last_entry;
|
||||
static VERTEXSHADERUID last_uid;
|
||||
};
|
||||
|
||||
} // namespace DX11
|
||||
|
||||
@@ -43,6 +43,7 @@ namespace DX9
|
||||
|
||||
PixelShaderCache::PSCache PixelShaderCache::PixelShaders;
|
||||
const PixelShaderCache::PSCacheEntry *PixelShaderCache::last_entry;
|
||||
PIXELSHADERUID PixelShaderCache::last_uid;
|
||||
|
||||
static LinearDiskCache<PIXELSHADERUID, u8> g_ps_disk_cache;
|
||||
static std::set<u32> unique_shaders;
|
||||
@@ -233,6 +234,8 @@ static LPDIRECT3DPIXELSHADER9 CreateCopyShader(int copyMatrixType, int depthConv
|
||||
|
||||
void PixelShaderCache::Init()
|
||||
{
|
||||
last_entry = NULL;
|
||||
|
||||
//program used for clear screen
|
||||
{
|
||||
char pprog[3072];
|
||||
@@ -283,6 +286,9 @@ void PixelShaderCache::Init()
|
||||
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());
|
||||
PixelShaderCacheInserter inserter;
|
||||
g_ps_disk_cache.OpenAndRead(cache_filename, inserter);
|
||||
|
||||
if (g_Config.bEnableShaderDebugging)
|
||||
Clear();
|
||||
}
|
||||
|
||||
// ONLY to be used during shutdown.
|
||||
@@ -292,7 +298,7 @@ void PixelShaderCache::Clear()
|
||||
iter->second.Destroy();
|
||||
PixelShaders.clear();
|
||||
|
||||
memset(&last_pixel_shader_uid, 0xFF, sizeof(last_pixel_shader_uid));
|
||||
last_entry = NULL;
|
||||
}
|
||||
|
||||
void PixelShaderCache::Shutdown()
|
||||
@@ -326,41 +332,47 @@ void PixelShaderCache::Shutdown()
|
||||
|
||||
bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components)
|
||||
{
|
||||
const API_TYPE api = ((D3D::GetCaps().PixelShaderVersion >> 8) & 0xFF) < 3 ? API_D3D9_SM20 : API_D3D9_SM30;
|
||||
PIXELSHADERUID uid;
|
||||
GetPixelShaderId(&uid, dstAlphaMode);
|
||||
GetPixelShaderId(&uid, dstAlphaMode, components);
|
||||
|
||||
// Check if the shader is already set
|
||||
if (uid == last_pixel_shader_uid && PixelShaders[uid].frameCount == frameCount)
|
||||
if (last_entry)
|
||||
{
|
||||
PSCache::const_iterator iter = PixelShaders.find(uid);
|
||||
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
|
||||
return (iter != PixelShaders.end() && iter->second.shader);
|
||||
if (uid == last_uid)
|
||||
{
|
||||
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
|
||||
ValidatePixelShaderIDs(api, last_entry->safe_uid, last_entry->code, dstAlphaMode, components);
|
||||
return last_entry->shader != NULL;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(&last_pixel_shader_uid, &uid, sizeof(PIXELSHADERUID));
|
||||
last_uid = uid;
|
||||
|
||||
// Check if the shader is already in the cache
|
||||
PSCache::iterator iter;
|
||||
iter = PixelShaders.find(uid);
|
||||
if (iter != PixelShaders.end())
|
||||
{
|
||||
iter->second.frameCount = frameCount;
|
||||
const PSCacheEntry &entry = iter->second;
|
||||
last_entry = &entry;
|
||||
|
||||
if (entry.shader) D3D::SetPixelShader(entry.shader);
|
||||
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
|
||||
ValidatePixelShaderIDs(api, entry.safe_uid, entry.code, dstAlphaMode, components);
|
||||
return (entry.shader != NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Need to compile a new shader
|
||||
const char *code = GeneratePixelShaderCode(dstAlphaMode, ((D3D::GetCaps().PixelShaderVersion >> 8) & 0xFF) < 3 ? API_D3D9_SM20 : API_D3D9_SM30, components);
|
||||
const char *code = GeneratePixelShaderCode(dstAlphaMode, api, components);
|
||||
|
||||
u32 code_hash = HashAdler32((const u8 *)code, strlen(code));
|
||||
unique_shaders.insert(code_hash);
|
||||
SETSTAT(stats.numUniquePixelShaders, unique_shaders.size());
|
||||
if (g_ActiveConfig.bEnableShaderDebugging)
|
||||
{
|
||||
u32 code_hash = HashAdler32((const u8 *)code, strlen(code));
|
||||
unique_shaders.insert(code_hash);
|
||||
SETSTAT(stats.numUniquePixelShaders, unique_shaders.size());
|
||||
}
|
||||
|
||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||
if (g_ActiveConfig.iLog & CONF_SAVESHADERS && code) {
|
||||
@@ -381,14 +393,19 @@ bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components)
|
||||
|
||||
// Insert the bytecode into the caches
|
||||
g_ps_disk_cache.Append(uid, bytecode, bytecodelen);
|
||||
g_ps_disk_cache.Sync();
|
||||
|
||||
// And insert it into the shader cache.
|
||||
bool result = InsertByteCode(uid, bytecode, bytecodelen, true);
|
||||
bool success = InsertByteCode(uid, bytecode, bytecodelen, true);
|
||||
delete [] bytecode;
|
||||
|
||||
if (g_ActiveConfig.bEnableShaderDebugging && success)
|
||||
{
|
||||
PixelShaders[uid].code = code;
|
||||
GetSafePixelShaderId(&PixelShaders[uid].safe_uid, dstAlphaMode, components);
|
||||
}
|
||||
|
||||
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
|
||||
return result;
|
||||
return success;
|
||||
}
|
||||
|
||||
bool PixelShaderCache::InsertByteCode(const PIXELSHADERUID &uid, const u8 *bytecode, int bytecodelen, bool activate)
|
||||
@@ -398,7 +415,6 @@ bool PixelShaderCache::InsertByteCode(const PIXELSHADERUID &uid, const u8 *bytec
|
||||
// Make an entry in the table
|
||||
PSCacheEntry newentry;
|
||||
newentry.shader = shader;
|
||||
newentry.frameCount = frameCount;
|
||||
PixelShaders[uid] = newentry;
|
||||
last_entry = &PixelShaders[uid];
|
||||
|
||||
|
||||
@@ -40,9 +40,11 @@ private:
|
||||
{
|
||||
LPDIRECT3DPIXELSHADER9 shader;
|
||||
bool owns_shader;
|
||||
int frameCount;
|
||||
|
||||
PSCacheEntry() : shader(NULL), owns_shader(true), frameCount(0) {}
|
||||
PIXELSHADERUIDSAFE safe_uid;
|
||||
std::string code;
|
||||
|
||||
PSCacheEntry() : shader(NULL), owns_shader(true) {}
|
||||
void Destroy()
|
||||
{
|
||||
if (shader && owns_shader)
|
||||
@@ -55,6 +57,7 @@ private:
|
||||
|
||||
static PSCache PixelShaders;
|
||||
static const PSCacheEntry *last_entry;
|
||||
static PIXELSHADERUID last_uid;
|
||||
static void Clear();
|
||||
|
||||
public:
|
||||
|
||||
@@ -38,6 +38,7 @@ namespace DX9
|
||||
|
||||
VertexShaderCache::VSCache VertexShaderCache::vshaders;
|
||||
const VertexShaderCache::VSCacheEntry *VertexShaderCache::last_entry;
|
||||
VERTEXSHADERUID VertexShaderCache::last_uid;
|
||||
|
||||
#define MAX_SSAA_SHADERS 3
|
||||
|
||||
@@ -151,6 +152,11 @@ void VertexShaderCache::Init()
|
||||
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());
|
||||
VertexShaderCacheInserter inserter;
|
||||
g_vs_disk_cache.OpenAndRead(cache_filename, inserter);
|
||||
|
||||
if (g_Config.bEnableShaderDebugging)
|
||||
Clear();
|
||||
|
||||
last_entry = NULL;
|
||||
}
|
||||
|
||||
void VertexShaderCache::Clear()
|
||||
@@ -159,7 +165,7 @@ void VertexShaderCache::Clear()
|
||||
iter->second.Destroy();
|
||||
vshaders.clear();
|
||||
|
||||
memset(&last_vertex_shader_uid, 0xFF, sizeof(last_vertex_shader_uid));
|
||||
last_entry = NULL;
|
||||
}
|
||||
|
||||
void VertexShaderCache::Shutdown()
|
||||
@@ -184,23 +190,27 @@ bool VertexShaderCache::SetShader(u32 components)
|
||||
{
|
||||
VERTEXSHADERUID uid;
|
||||
GetVertexShaderId(&uid, components);
|
||||
if (uid == last_vertex_shader_uid && vshaders[uid].frameCount == frameCount)
|
||||
if (last_entry)
|
||||
{
|
||||
GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true);
|
||||
return (vshaders[uid].shader != NULL);
|
||||
if (uid == last_uid)
|
||||
{
|
||||
GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true);
|
||||
ValidateVertexShaderIDs(API_D3D9, last_entry->safe_uid, last_entry->code, components);
|
||||
return (last_entry->shader != NULL);
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(&last_vertex_shader_uid, &uid, sizeof(VERTEXSHADERUID));
|
||||
last_uid = uid;
|
||||
|
||||
VSCache::iterator iter = vshaders.find(uid);
|
||||
if (iter != vshaders.end())
|
||||
{
|
||||
iter->second.frameCount = frameCount;
|
||||
const VSCacheEntry &entry = iter->second;
|
||||
last_entry = &entry;
|
||||
|
||||
if (entry.shader) D3D::SetVertexShader(entry.shader);
|
||||
GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true);
|
||||
ValidateVertexShaderIDs(API_D3D9, entry.safe_uid, entry.code, components);
|
||||
return (entry.shader != NULL);
|
||||
}
|
||||
|
||||
@@ -213,12 +223,16 @@ bool VertexShaderCache::SetShader(u32 components)
|
||||
return false;
|
||||
}
|
||||
g_vs_disk_cache.Append(uid, bytecode, bytecodelen);
|
||||
g_vs_disk_cache.Sync();
|
||||
|
||||
bool result = InsertByteCode(uid, bytecode, bytecodelen, true);
|
||||
bool success = InsertByteCode(uid, bytecode, bytecodelen, true);
|
||||
if (g_ActiveConfig.bEnableShaderDebugging && success)
|
||||
{
|
||||
vshaders[uid].code = code;
|
||||
GetSafeVertexShaderId(&vshaders[uid].safe_uid, components);
|
||||
}
|
||||
delete [] bytecode;
|
||||
GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true);
|
||||
return result;
|
||||
return success;
|
||||
}
|
||||
|
||||
bool VertexShaderCache::InsertByteCode(const VERTEXSHADERUID &uid, const u8 *bytecode, int bytecodelen, bool activate) {
|
||||
@@ -227,7 +241,6 @@ bool VertexShaderCache::InsertByteCode(const VERTEXSHADERUID &uid, const u8 *byt
|
||||
// Make an entry in the table
|
||||
VSCacheEntry entry;
|
||||
entry.shader = shader;
|
||||
entry.frameCount = frameCount;
|
||||
|
||||
vshaders[uid] = entry;
|
||||
last_entry = &vshaders[uid];
|
||||
|
||||
@@ -34,11 +34,11 @@ private:
|
||||
struct VSCacheEntry
|
||||
{
|
||||
LPDIRECT3DVERTEXSHADER9 shader;
|
||||
int frameCount;
|
||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||
|
||||
std::string code;
|
||||
#endif
|
||||
VSCacheEntry() : shader(NULL), frameCount(0) {}
|
||||
VERTEXSHADERUIDSAFE safe_uid;
|
||||
|
||||
VSCacheEntry() : shader(NULL) {}
|
||||
void Destroy()
|
||||
{
|
||||
if (shader)
|
||||
@@ -51,6 +51,7 @@ private:
|
||||
|
||||
static VSCache vshaders;
|
||||
static const VSCacheEntry *last_entry;
|
||||
static VERTEXSHADERUID last_uid;
|
||||
static void Clear();
|
||||
|
||||
public:
|
||||
|
||||
@@ -44,7 +44,8 @@ bool PixelShaderCache::s_displayCompileAlert;
|
||||
GLuint PixelShaderCache::CurrentShader;
|
||||
bool PixelShaderCache::ShaderEnabled;
|
||||
|
||||
static FRAGMENTSHADER* pShaderLast = NULL;
|
||||
PixelShaderCache::PSCacheEntry* PixelShaderCache::last_entry = NULL;
|
||||
PIXELSHADERUID PixelShaderCache::last_uid;
|
||||
|
||||
GLuint PixelShaderCache::GetDepthMatrixProgram()
|
||||
{
|
||||
@@ -61,10 +62,9 @@ void PixelShaderCache::Init()
|
||||
glEnable(GL_FRAGMENT_PROGRAM_ARB);
|
||||
ShaderEnabled = true;
|
||||
CurrentShader = 0;
|
||||
last_entry = NULL;
|
||||
GL_REPORT_ERRORD();
|
||||
|
||||
memset(&last_pixel_shader_uid, 0xFF, sizeof(last_pixel_shader_uid));
|
||||
|
||||
s_displayCompileAlert = true;
|
||||
|
||||
glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB, (GLint *)&s_nMaxPixelInstructions);
|
||||
@@ -184,38 +184,43 @@ void PixelShaderCache::Shutdown()
|
||||
FRAGMENTSHADER* PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components)
|
||||
{
|
||||
PIXELSHADERUID uid;
|
||||
GetPixelShaderId(&uid, dstAlphaMode);
|
||||
|
||||
GetPixelShaderId(&uid, dstAlphaMode, components);
|
||||
|
||||
// Check if the shader is already set
|
||||
if (uid == last_pixel_shader_uid && PixelShaders[uid].frameCount == frameCount)
|
||||
if (last_entry)
|
||||
{
|
||||
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
|
||||
return pShaderLast;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(&last_pixel_shader_uid, &uid, sizeof(PIXELSHADERUID));
|
||||
last_uid = uid;
|
||||
|
||||
PSCache::iterator iter = PixelShaders.find(uid);
|
||||
|
||||
if (iter != PixelShaders.end())
|
||||
{
|
||||
iter->second.frameCount = frameCount;
|
||||
PSCacheEntry &entry = iter->second;
|
||||
if (&entry.shader != pShaderLast)
|
||||
{
|
||||
pShaderLast = &entry.shader;
|
||||
}
|
||||
last_entry = &entry;
|
||||
|
||||
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
|
||||
return pShaderLast;
|
||||
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];
|
||||
newentry.frameCount = frameCount;
|
||||
pShaderLast = &newentry.shader;
|
||||
last_entry = &newentry;
|
||||
const char *code = GeneratePixelShaderCode(dstAlphaMode, API_OPENGL, components);
|
||||
|
||||
if (g_ActiveConfig.bEnableShaderDebugging && code)
|
||||
{
|
||||
GetSafePixelShaderId(&newentry.safe_uid, dstAlphaMode, components);
|
||||
newentry.shader.strprog = code;
|
||||
}
|
||||
|
||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||
if (g_ActiveConfig.iLog & CONF_SAVESHADERS && code) {
|
||||
static int counter = 0;
|
||||
@@ -234,7 +239,7 @@ FRAGMENTSHADER* PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 comp
|
||||
INCSTAT(stats.numPixelShadersCreated);
|
||||
SETSTAT(stats.numPixelShadersAlive, PixelShaders.size());
|
||||
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
|
||||
return pShaderLast;
|
||||
return &last_entry->shader;
|
||||
}
|
||||
|
||||
bool PixelShaderCache::CompilePixelShader(FRAGMENTSHADER& ps, const char* pstrprogram)
|
||||
@@ -318,9 +323,6 @@ bool PixelShaderCache::CompilePixelShader(FRAGMENTSHADER& ps, const char* pstrpr
|
||||
cgDestroyProgram(tempprog);
|
||||
#endif
|
||||
|
||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||
ps.strprog = pstrprogram;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,9 +39,7 @@ struct FRAGMENTSHADER
|
||||
}
|
||||
}
|
||||
GLuint glprogid; // opengl program id
|
||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||
std::string strprog;
|
||||
#endif
|
||||
};
|
||||
|
||||
class PixelShaderCache
|
||||
@@ -49,13 +47,13 @@ class PixelShaderCache
|
||||
struct PSCacheEntry
|
||||
{
|
||||
FRAGMENTSHADER shader;
|
||||
int frameCount;
|
||||
PSCacheEntry() : frameCount(0) {}
|
||||
PSCacheEntry() {}
|
||||
~PSCacheEntry() {}
|
||||
void Destroy()
|
||||
{
|
||||
shader.Destroy();
|
||||
}
|
||||
PIXELSHADERUIDSAFE safe_uid;
|
||||
};
|
||||
|
||||
typedef std::map<PIXELSHADERUID, PSCacheEntry> PSCache;
|
||||
@@ -67,6 +65,8 @@ class PixelShaderCache
|
||||
static bool s_displayCompileAlert;
|
||||
|
||||
static GLuint CurrentShader;
|
||||
static PSCacheEntry* last_entry;
|
||||
static PIXELSHADERUID last_uid;
|
||||
|
||||
static bool ShaderEnabled;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user