mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-09-22 20:36:22 +02:00
cleanup shader manager
This commit is contained in:
+139
-158
@@ -96,28 +96,31 @@ LinkedShader::LinkedShader(VSShader *vs, PSShader *fs, bool useHWTransform)
|
||||
m_vs = vs;
|
||||
m_fs = fs;
|
||||
|
||||
u_tex = GetConstantByName("tex");
|
||||
u_proj = GetConstantByName("u_proj");
|
||||
u_proj_through = GetConstantByName("u_proj_through");
|
||||
u_texenv = GetConstantByName("u_texenv");
|
||||
u_fogcolor = GetConstantByName("u_fogcolor");
|
||||
u_fogcoef = GetConstantByName("u_fogcoef");
|
||||
u_alphacolorref = GetConstantByName("u_alphacolorref");
|
||||
u_colormask = GetConstantByName("u_colormask");
|
||||
u_tex = GetConstantByName("tex");
|
||||
u_proj = GetConstantByName("u_proj");
|
||||
u_proj_through = GetConstantByName("u_proj_through");
|
||||
u_texenv = GetConstantByName("u_texenv");
|
||||
u_fogcolor = GetConstantByName("u_fogcolor");
|
||||
u_fogcoef = GetConstantByName("u_fogcoef");
|
||||
u_alphacolorref = GetConstantByName("u_alphacolorref");
|
||||
u_colormask = GetConstantByName("u_colormask");
|
||||
|
||||
// Transform
|
||||
u_view = GetConstantByName("u_view");
|
||||
u_world = GetConstantByName("u_world");
|
||||
u_texmtx = GetConstantByName("u_texmtx");
|
||||
u_view = GetConstantByName("u_view");
|
||||
u_world = GetConstantByName("u_world");
|
||||
u_texmtx = GetConstantByName("u_texmtx");
|
||||
|
||||
if (gstate.getWeightMask() != 0)
|
||||
numBones = TranslateNumBones(gstate.getNumBoneWeights());
|
||||
else
|
||||
numBones = 0;
|
||||
|
||||
numBones = gstate.getNumBoneWeights();
|
||||
#ifdef USE_BONE_ARRAY
|
||||
u_bone = glGetUniformLocation(program, "u_bone");
|
||||
#else
|
||||
for (int i = 0; i < numBones; i++) {
|
||||
for (int i = 0; i < 8; i++) {
|
||||
char name[10];
|
||||
sprintf(name, "u_bone%i", i);
|
||||
// u_bone[i] = glGetUniformLocation(program, name);
|
||||
u_bone[i] = GetConstantByName(name);
|
||||
}
|
||||
#endif
|
||||
@@ -176,6 +179,70 @@ LinkedShader::~LinkedShader() {
|
||||
// glDeleteProgram(program);
|
||||
}
|
||||
|
||||
void LinkedShader::SetFloatArray(D3DXHANDLE uniform, const float* pArray, int len) {
|
||||
if (m_fs->constant->SetFloatArray(pD3Ddevice, uniform, pArray, len) == D3D_OK);
|
||||
else
|
||||
m_vs->constant->SetFloatArray(pD3Ddevice, uniform, pArray, len);
|
||||
}
|
||||
|
||||
void LinkedShader::SetFloat(D3DXHANDLE uniform, float value) {
|
||||
if (m_fs->constant->SetFloat(pD3Ddevice, uniform, value) == D3D_OK);
|
||||
else
|
||||
m_vs->constant->SetFloat(pD3Ddevice, uniform, value);
|
||||
}
|
||||
|
||||
|
||||
// Utility
|
||||
void LinkedShader::SetColorUniform3(D3DXHANDLE uniform, u32 color) {
|
||||
const float col[3] = {
|
||||
((color & 0xFF)) / 255.0f,
|
||||
((color & 0xFF00) >> 8) / 255.0f,
|
||||
((color & 0xFF0000) >> 16) / 255.0f
|
||||
};
|
||||
SetFloatArray(uniform, col, 4);
|
||||
}
|
||||
|
||||
|
||||
void LinkedShader::SetColorUniform3Alpha(D3DXHANDLE uniform, u32 color, u8 alpha) {
|
||||
const float col[4] = {
|
||||
((color & 0xFF)) / 255.0f,
|
||||
((color & 0xFF00) >> 8) / 255.0f,
|
||||
((color & 0xFF0000) >> 16) / 255.0f,
|
||||
alpha/255.0f
|
||||
};
|
||||
SetFloatArray(uniform, col, 4);
|
||||
}
|
||||
|
||||
void LinkedShader::SetColorUniform3Alpha255(D3DXHANDLE uniform, u32 color, u8 alpha) {
|
||||
if (1) {
|
||||
const float col[4] = {
|
||||
(float)((color & 0xFF)) * (1.0f / 255.0f),
|
||||
(float)((color & 0xFF00) >> 8) * (1.0f / 255.0f),
|
||||
(float)((color & 0xFF0000) >> 16) * (1.0f / 255.0f),
|
||||
(float)alpha * (1.0f / 255.0f)
|
||||
};
|
||||
SetFloatArray(uniform, col, 4);
|
||||
} else {
|
||||
const float col[4] = {
|
||||
(float)((color & 0xFF)) ,
|
||||
(float)((color & 0xFF00) >> 8) ,
|
||||
(float)((color & 0xFF0000) >> 16) ,
|
||||
(float)alpha
|
||||
};
|
||||
SetFloatArray(uniform, col, 4);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LinkedShader::SetColorUniform3ExtraFloat(D3DXHANDLE uniform, u32 color, float extra) {
|
||||
const float col[4] = {
|
||||
((color & 0xFF)) / 255.0f,
|
||||
((color & 0xFF00) >> 8) / 255.0f,
|
||||
((color & 0xFF0000) >> 16) / 255.0f,
|
||||
extra
|
||||
};
|
||||
SetFloatArray(uniform, col, 4);
|
||||
}
|
||||
|
||||
static void ConvertMatrix4x3To4x4(const float *m4x3, float *m4x4) {
|
||||
m4x4[0] = m4x3[0];
|
||||
@@ -214,97 +281,6 @@ void LinkedShader::SetMatrix(D3DXHANDLE uniform, const float* pMatrix) {
|
||||
m_fs->constant->SetMatrix(pD3Ddevice, uniform, pDxMat);
|
||||
}
|
||||
|
||||
void LinkedShader::SetColorUniform3(D3DXHANDLE uniform, u32 color) {
|
||||
const float col[3] = {
|
||||
((color & 0xFF)) / 255.0f,
|
||||
((color & 0xFF00) >> 8) / 255.0f,
|
||||
((color & 0xFF0000) >> 16) / 255.0f
|
||||
};
|
||||
SetFloatArray(uniform, col, 4);
|
||||
}
|
||||
|
||||
void LinkedShader::SetColorUniform3ExtraFloat(D3DXHANDLE uniform, u32 color, float extra) {
|
||||
const float col[4] = {
|
||||
((color & 0xFF)) / 255.0f,
|
||||
((color & 0xFF00) >> 8) / 255.0f,
|
||||
((color & 0xFF0000) >> 16) / 255.0f,
|
||||
extra
|
||||
};
|
||||
SetFloatArray(uniform, col, 4);
|
||||
}
|
||||
|
||||
void LinkedShader::SetColorUniform3Alpha(D3DXHANDLE uniform, u32 color, u8 alpha) {
|
||||
const float col[4] = {
|
||||
((color & 0xFF)) / 255.0f,
|
||||
((color & 0xFF00) >> 8) / 255.0f,
|
||||
((color & 0xFF0000) >> 16) / 255.0f,
|
||||
alpha/255.0f
|
||||
};
|
||||
SetFloatArray(uniform, col, 4);
|
||||
}
|
||||
|
||||
void LinkedShader::SetColorUniform3Alpha255(D3DXHANDLE uniform, u32 color, u8 alpha) {
|
||||
if (1) {
|
||||
const float col[4] = {
|
||||
(float)((color & 0xFF)) * (1.0f / 255.0f),
|
||||
(float)((color & 0xFF00) >> 8) * (1.0f / 255.0f),
|
||||
(float)((color & 0xFF0000) >> 16) * (1.0f / 255.0f),
|
||||
(float)alpha * (1.0f / 255.0f)
|
||||
};
|
||||
SetFloatArray(uniform, col, 4);
|
||||
} else {
|
||||
const float col[4] = {
|
||||
(float)((color & 0xFF)) ,
|
||||
(float)((color & 0xFF00) >> 8) ,
|
||||
(float)((color & 0xFF0000) >> 16) ,
|
||||
(float)alpha
|
||||
};
|
||||
SetFloatArray(uniform, col, 4);
|
||||
}
|
||||
}
|
||||
|
||||
void LinkedShader::SetFloatArray(D3DXHANDLE uniform, const float* pArray, int len) {
|
||||
if (m_fs->constant->SetFloatArray(pD3Ddevice, uniform, pArray, len) == D3D_OK);
|
||||
else
|
||||
m_vs->constant->SetFloatArray(pD3Ddevice, uniform, pArray, len);
|
||||
}
|
||||
|
||||
void LinkedShader::SetFloat(D3DXHANDLE uniform, float value) {
|
||||
if (m_fs->constant->SetFloat(pD3Ddevice, uniform, value) == D3D_OK);
|
||||
else
|
||||
m_vs->constant->SetFloat(pD3Ddevice, uniform, value);
|
||||
}
|
||||
|
||||
void LinkedShader::use() {
|
||||
|
||||
updateUniforms();
|
||||
/*
|
||||
glUseProgram(program);
|
||||
updateUniforms();
|
||||
glEnableVertexAttribArray(a_position);
|
||||
if (a_texcoord != -1) glEnableVertexAttribArray(a_texcoord);
|
||||
if (a_color0 != -1) glEnableVertexAttribArray(a_color0);
|
||||
if (a_color1 != -1) glEnableVertexAttribArray(a_color1);
|
||||
if (a_normal != -1) glEnableVertexAttribArray(a_normal);
|
||||
if (a_weight0123 != -1) glEnableVertexAttribArray(a_weight0123);
|
||||
if (a_weight4567 != -1) glEnableVertexAttribArray(a_weight4567);
|
||||
*/
|
||||
pD3Ddevice->SetPixelShader(m_fs->shader);
|
||||
pD3Ddevice->SetVertexShader(m_vs->shader);
|
||||
}
|
||||
|
||||
void LinkedShader::stop() {
|
||||
/*
|
||||
glDisableVertexAttribArray(a_position);
|
||||
if (a_texcoord != -1) glDisableVertexAttribArray(a_texcoord);
|
||||
if (a_color0 != -1) glDisableVertexAttribArray(a_color0);
|
||||
if (a_color1 != -1) glDisableVertexAttribArray(a_color1);
|
||||
if (a_normal != -1) glDisableVertexAttribArray(a_normal);
|
||||
if (a_weight0123 != -1) glDisableVertexAttribArray(a_weight0123);
|
||||
if (a_weight4567 != -1) glDisableVertexAttribArray(a_weight4567);
|
||||
*/
|
||||
}
|
||||
|
||||
// Depth in ogl is between -1;1 we need between 0;1
|
||||
static void ConvertMatrices(Matrix4x4 & in) {
|
||||
/*
|
||||
@@ -319,6 +295,18 @@ static void ConvertMatrices(Matrix4x4 & in) {
|
||||
in = in * t;
|
||||
}
|
||||
|
||||
void LinkedShader::use() {
|
||||
|
||||
updateUniforms();
|
||||
|
||||
pD3Ddevice->SetPixelShader(m_fs->shader);
|
||||
pD3Ddevice->SetVertexShader(m_vs->shader);
|
||||
}
|
||||
|
||||
void LinkedShader::stop() {
|
||||
|
||||
}
|
||||
|
||||
void LinkedShader::updateUniforms() {
|
||||
if (!dirtyUniforms)
|
||||
return;
|
||||
@@ -367,8 +355,7 @@ void LinkedShader::updateUniforms() {
|
||||
getFloat24(gstate.fog1),
|
||||
getFloat24(gstate.fog2),
|
||||
};
|
||||
//glUniform2fv(u_fogcoef, 1, fogcoef);
|
||||
m_vs->constant->SetFloatArray(pD3Ddevice, u_fogcoef, fogcoef, 2);
|
||||
SetFloatArray(u_fogcoef, fogcoef, 2);
|
||||
}
|
||||
|
||||
// Texturing
|
||||
@@ -382,11 +369,11 @@ void LinkedShader::updateUniforms() {
|
||||
uvscaleoff[2] = gstate_c.uv.uOff / gstate_c.curTextureWidth;
|
||||
uvscaleoff[3] = gstate_c.uv.vOff / gstate_c.curTextureHeight;
|
||||
} else {
|
||||
int w = 1 << (gstate.texsize[0] & 0xf);
|
||||
int h = 1 << ((gstate.texsize[0] >> 8) & 0xf);
|
||||
int w = gstate.getTextureWidth(0);
|
||||
int h = gstate.getTextureHeight(0);
|
||||
float widthFactor = (float)w / (float)gstate_c.curTextureWidth;
|
||||
float heightFactor = (float)h / (float)gstate_c.curTextureHeight;
|
||||
if ((gstate.texmapmode & 3) == 0) {
|
||||
if (gstate.getUVGenMode() == 0) {
|
||||
static const float rescale[4] = {1.0f, 2*127.5f/128.f, 2*32767.5f/32768.f, 1.0f};
|
||||
float factor = rescale[(gstate.vertType & GE_VTYPE_TC_MASK) >> GE_VTYPE_TC_SHIFT];
|
||||
uvscaleoff[0] = gstate_c.uv.uScale * factor * widthFactor;
|
||||
@@ -444,8 +431,7 @@ void LinkedShader::updateUniforms() {
|
||||
for (int i = 0; i < numBones; i++) {
|
||||
if (dirtyUniforms & (DIRTY_BONEMATRIX0 << i)) {
|
||||
ConvertMatrix4x3To4x4(gstate.boneMatrix + 12 * i, bonetemp);
|
||||
//glUniformMatrix4fv(u_bone[i], 1, GL_FALSE, bonetemp);
|
||||
|
||||
|
||||
if (u_bone[i] != 0)
|
||||
SetMatrix(u_bone[i], bonetemp);
|
||||
}
|
||||
@@ -512,7 +498,7 @@ void LinkedShader::updateUniforms() {
|
||||
dirtyUniforms = 0;
|
||||
}
|
||||
|
||||
ShaderManager::ShaderManager() : lastShader(NULL), globalDirty(0xFFFFFFFF), shaderSwitchDirty(0) {
|
||||
ShaderManager::ShaderManager() : lastShader_(NULL), globalDirty_(0xFFFFFFFF), shaderSwitchDirty_(0) {
|
||||
codeBuffer_ = new char[16384];
|
||||
}
|
||||
|
||||
@@ -520,27 +506,22 @@ ShaderManager::~ShaderManager() {
|
||||
delete [] codeBuffer_;
|
||||
}
|
||||
|
||||
|
||||
void ShaderManager::DirtyUniform(u32 what) {
|
||||
globalDirty |= what;
|
||||
}
|
||||
|
||||
void ShaderManager::Clear() {
|
||||
for (auto iter = linkedShaderCache.begin(); iter != linkedShaderCache.end(); ++iter) {
|
||||
for (auto iter = linkedShaderCache_.begin(); iter != linkedShaderCache_.end(); ++iter) {
|
||||
delete iter->ls;
|
||||
}
|
||||
for (auto iter = fsCache.begin(); iter != fsCache.end(); ++iter) {
|
||||
for (auto iter = fsCache_.begin(); iter != fsCache_.end(); ++iter) {
|
||||
delete iter->second;
|
||||
}
|
||||
for (auto iter = vsCache.begin(); iter != vsCache.end(); ++iter) {
|
||||
for (auto iter = vsCache_.begin(); iter != vsCache_.end(); ++iter) {
|
||||
delete iter->second;
|
||||
}
|
||||
linkedShaderCache.clear();
|
||||
fsCache.clear();
|
||||
vsCache.clear();
|
||||
globalDirty = 0xFFFFFFFF;
|
||||
lastFSID.clear();
|
||||
lastVSID.clear();
|
||||
linkedShaderCache_.clear();
|
||||
fsCache_.clear();
|
||||
vsCache_.clear();
|
||||
globalDirty_ = 0xFFFFFFFF;
|
||||
lastFSID_.clear();
|
||||
lastVSID_.clear();
|
||||
DirtyShader();
|
||||
}
|
||||
|
||||
@@ -551,26 +532,26 @@ void ShaderManager::ClearCache(bool deleteThem) {
|
||||
|
||||
void ShaderManager::DirtyShader() {
|
||||
// Forget the last shader ID
|
||||
lastFSID.clear();
|
||||
lastVSID.clear();
|
||||
lastShader = 0;
|
||||
globalDirty = 0xFFFFFFFF;
|
||||
shaderSwitchDirty = 0;
|
||||
lastFSID_.clear();
|
||||
lastVSID_.clear();
|
||||
lastShader_ = 0;
|
||||
globalDirty_ = 0xFFFFFFFF;
|
||||
shaderSwitchDirty_ = 0;
|
||||
}
|
||||
|
||||
void ShaderManager::EndFrame() { // disables vertex arrays
|
||||
if (lastShader)
|
||||
lastShader->stop();
|
||||
lastShader = 0;
|
||||
if (lastShader_)
|
||||
lastShader_->stop();
|
||||
lastShader_ = 0;
|
||||
}
|
||||
|
||||
|
||||
LinkedShader *ShaderManager::ApplyShader(int prim) {
|
||||
if (globalDirty) {
|
||||
if (lastShader)
|
||||
lastShader->dirtyUniforms |= globalDirty;
|
||||
shaderSwitchDirty |= globalDirty;
|
||||
globalDirty = 0;
|
||||
if (globalDirty_) {
|
||||
if (lastShader_)
|
||||
lastShader_->dirtyUniforms |= globalDirty_;
|
||||
shaderSwitchDirty_ |= globalDirty_;
|
||||
globalDirty_ = 0;
|
||||
}
|
||||
|
||||
bool useHWTransform = CanUseHardwareTransform(prim);
|
||||
@@ -581,22 +562,22 @@ LinkedShader *ShaderManager::ApplyShader(int prim) {
|
||||
ComputeFragmentShaderID(&FSID);
|
||||
|
||||
// Just update uniforms if this is the same shader as last time.
|
||||
if (lastShader != 0 && VSID == lastVSID && FSID == lastFSID) {
|
||||
lastShader->updateUniforms();
|
||||
return lastShader; // Already all set.
|
||||
if (lastShader_ != 0 && VSID == lastVSID_ && FSID == lastFSID_) {
|
||||
lastShader_->updateUniforms();
|
||||
return lastShader_; // Already all set.
|
||||
}
|
||||
|
||||
if (lastShader != 0) {
|
||||
if (lastShader_ != 0) {
|
||||
// There was a previous shader and we're switching.
|
||||
lastShader->stop();
|
||||
lastShader_->stop();
|
||||
}
|
||||
|
||||
lastVSID = VSID;
|
||||
lastFSID = FSID;
|
||||
lastVSID_ = VSID;
|
||||
lastFSID_ = FSID;
|
||||
|
||||
VSCache::iterator vsIter = vsCache.find(VSID);
|
||||
VSCache::iterator vsIter = vsCache_.find(VSID);
|
||||
VSShader *vs;
|
||||
if (vsIter == vsCache.end()) {
|
||||
if (vsIter == vsCache_.end()) {
|
||||
// Vertex shader not in cache. Let's compile it.
|
||||
GenerateVertexShader(prim, codeBuffer_, useHWTransform);
|
||||
vs = new VSShader(codeBuffer_, useHWTransform);
|
||||
@@ -615,18 +596,18 @@ LinkedShader *ShaderManager::ApplyShader(int prim) {
|
||||
vs = new VSShader(codeBuffer_, false);
|
||||
}
|
||||
|
||||
vsCache[VSID] = vs;
|
||||
vsCache_[VSID] = vs;
|
||||
} else {
|
||||
vs = vsIter->second;
|
||||
}
|
||||
|
||||
FSCache::iterator fsIter = fsCache.find(FSID);
|
||||
FSCache::iterator fsIter = fsCache_.find(FSID);
|
||||
PSShader *fs;
|
||||
if (fsIter == fsCache.end()) {
|
||||
if (fsIter == fsCache_.end()) {
|
||||
// Fragment shader not in cache. Let's compile it.
|
||||
GenerateFragmentShader(codeBuffer_);
|
||||
fs = new PSShader(codeBuffer_, useHWTransform);
|
||||
fsCache[FSID] = fs;
|
||||
fsCache_[FSID] = fs;
|
||||
} else {
|
||||
fs = fsIter->second;
|
||||
}
|
||||
@@ -634,24 +615,24 @@ LinkedShader *ShaderManager::ApplyShader(int prim) {
|
||||
// Okay, we have both shaders. Let's see if there's a linked one.
|
||||
LinkedShader *ls = NULL;
|
||||
|
||||
for (auto iter = linkedShaderCache.begin(); iter != linkedShaderCache.end(); ++iter) {
|
||||
for (auto iter = linkedShaderCache_.begin(); iter != linkedShaderCache_.end(); ++iter) {
|
||||
// Deferred dirtying! Let's see if we can make this even more clever later.
|
||||
iter->ls->dirtyUniforms |= shaderSwitchDirty;
|
||||
iter->ls->dirtyUniforms |= shaderSwitchDirty_;
|
||||
|
||||
if (iter->vs == vs && iter->fs == fs) {
|
||||
ls = iter->ls;
|
||||
}
|
||||
}
|
||||
shaderSwitchDirty = 0;
|
||||
shaderSwitchDirty_ = 0;
|
||||
|
||||
if (ls == NULL) {
|
||||
ls = new LinkedShader(vs, fs, vs->UseHWTransform()); // This does "use" automatically
|
||||
const LinkedShaderCacheEntry entry(vs, fs, ls);
|
||||
linkedShaderCache.push_back(entry);
|
||||
linkedShaderCache_.push_back(entry);
|
||||
} else {
|
||||
ls->use();
|
||||
}
|
||||
|
||||
lastShader = ls;
|
||||
lastShader_ = ls;
|
||||
return ls;
|
||||
}
|
||||
|
||||
@@ -189,12 +189,14 @@ public:
|
||||
void ClearCache(bool deleteThem); // TODO: deleteThem currently not respected
|
||||
LinkedShader *ApplyShader(int prim);
|
||||
void DirtyShader();
|
||||
void DirtyUniform(u32 what);
|
||||
void DirtyUniform(u32 what) {
|
||||
globalDirty_ |= what;
|
||||
}
|
||||
void EndFrame(); // disables vertex arrays
|
||||
|
||||
int NumVertexShaders() const { return (int)vsCache.size(); }
|
||||
int NumFragmentShaders() const { return (int)fsCache.size(); }
|
||||
int NumPrograms() const { return (int)linkedShaderCache.size(); }
|
||||
int NumVertexShaders() const { return (int)vsCache_.size(); }
|
||||
int NumFragmentShaders() const { return (int)fsCache_.size(); }
|
||||
int NumPrograms() const { return (int)linkedShaderCache_.size(); }
|
||||
|
||||
private:
|
||||
void Clear();
|
||||
@@ -210,19 +212,19 @@ private:
|
||||
};
|
||||
typedef std::vector<LinkedShaderCacheEntry> LinkedShaderCache;
|
||||
|
||||
LinkedShaderCache linkedShaderCache;
|
||||
FragmentShaderID lastFSID;
|
||||
VertexShaderID lastVSID;
|
||||
LinkedShaderCache linkedShaderCache_;
|
||||
FragmentShaderID lastFSID_;
|
||||
VertexShaderID lastVSID_;
|
||||
|
||||
LinkedShader *lastShader;
|
||||
u32 globalDirty;
|
||||
u32 shaderSwitchDirty;
|
||||
LinkedShader *lastShader_;
|
||||
u32 globalDirty_;
|
||||
u32 shaderSwitchDirty_;
|
||||
char *codeBuffer_;
|
||||
|
||||
typedef std::map<FragmentShaderID, PSShader *> FSCache;
|
||||
FSCache fsCache;
|
||||
FSCache fsCache_;
|
||||
|
||||
typedef std::map<VertexShaderID, VSShader *> VSCache;
|
||||
VSCache vsCache;
|
||||
VSCache vsCache_;
|
||||
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user