mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-15 02:29:51 +01:00
Split up ApplyShader into ApplyVertexShader and ApplyFragmentShader.
Will allow the alphatest avoiding optimization later.
This commit is contained in:
1 parent
893a719c4e
commit
f2f0355d94
3 files changed
+34
-14
No files matched your search
+18
-11
@@ -82,7 +82,7 @@ Shader::~Shader() {
|
||||
LinkedShader::LinkedShader(Shader *vs, Shader *fs, u32 vertType, bool useHWTransform, LinkedShader *previous)
|
||||
: useHWTransform_(useHWTransform), program(0), dirtyUniforms(0) {
|
||||
program = glCreateProgram();
|
||||
|
||||
vs_ = vs;
|
||||
glAttachShader(program, vs->shader);
|
||||
glAttachShader(program, fs->shader);
|
||||
|
||||
@@ -605,8 +605,7 @@ void ShaderManager::DirtyLastShader() { // disables vertex arrays
|
||||
lastShader_ = 0;
|
||||
}
|
||||
|
||||
|
||||
LinkedShader *ShaderManager::ApplyShader(int prim, u32 vertType) {
|
||||
Shader *ShaderManager::ApplyVertexShader(int prim, u32 vertType) {
|
||||
// This doesn't work - we miss some events that really do need to dirty the prescale.
|
||||
// like changing the texmapmode.
|
||||
// if (g_Config.bPrescaleUV)
|
||||
@@ -622,18 +621,20 @@ LinkedShader *ShaderManager::ApplyShader(int prim, u32 vertType) {
|
||||
bool useHWTransform = CanUseHardwareTransform(prim);
|
||||
|
||||
VertexShaderID VSID;
|
||||
FragmentShaderID FSID;
|
||||
ComputeVertexShaderID(&VSID, vertType, prim, useHWTransform);
|
||||
ComputeFragmentShaderID(&FSID);
|
||||
ComputeFragmentShaderID(&FSID_);
|
||||
|
||||
// Just update uniforms if this is the same shader as last time.
|
||||
if (lastShader_ != 0 && VSID == lastVSID_ && FSID == lastFSID_) {
|
||||
if (lastShader_ != 0 && VSID == lastVSID_ && FSID_ == lastFSID_) {
|
||||
lastShader_->UpdateUniforms(vertType);
|
||||
return lastShader_; // Already all set.
|
||||
lastShaderSame_ = true;
|
||||
return lastShader_->vs_; // Already all set.
|
||||
} else {
|
||||
lastShaderSame_ = false;
|
||||
}
|
||||
|
||||
lastVSID_ = VSID;
|
||||
lastFSID_ = FSID;
|
||||
lastFSID_ = FSID_;
|
||||
|
||||
VSCache::iterator vsIter = vsCache_.find(VSID);
|
||||
Shader *vs;
|
||||
@@ -660,14 +661,20 @@ LinkedShader *ShaderManager::ApplyShader(int prim, u32 vertType) {
|
||||
} else {
|
||||
vs = vsIter->second;
|
||||
}
|
||||
return vs;
|
||||
}
|
||||
|
||||
FSCache::iterator fsIter = fsCache_.find(FSID);
|
||||
LinkedShader *ShaderManager::ApplyFragmentShader(Shader *vs, int prim, u32 vertType) {
|
||||
if (lastShaderSame_)
|
||||
return lastShader_;
|
||||
|
||||
FSCache::iterator fsIter = fsCache_.find(FSID_);
|
||||
Shader *fs;
|
||||
if (fsIter == fsCache_.end()) {
|
||||
// Fragment shader not in cache. Let's compile it.
|
||||
GenerateFragmentShader(codeBuffer_);
|
||||
fs = new Shader(codeBuffer_, GL_FRAGMENT_SHADER, useHWTransform);
|
||||
fsCache_[FSID] = fs;
|
||||
fs = new Shader(codeBuffer_, GL_FRAGMENT_SHADER, vs->UseHWTransform());
|
||||
fsCache_[FSID_] = fs;
|
||||
} else {
|
||||
fs = fsIter->second;
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ public:
|
||||
void stop();
|
||||
void UpdateUniforms(u32 vertType);
|
||||
|
||||
Shader *vs_;
|
||||
// Set to false if the VS failed, happens on Mali-400 a lot for complex shaders.
|
||||
bool useHWTransform_;
|
||||
|
||||
@@ -167,7 +168,12 @@ public:
|
||||
~ShaderManager();
|
||||
|
||||
void ClearCache(bool deleteThem); // TODO: deleteThem currently not respected
|
||||
LinkedShader *ApplyShader(int prim, u32 vertType);
|
||||
|
||||
// This is the old ApplyShader split into two parts, because of annoying information dependencies.
|
||||
// If you call ApplyVertexShader, you MUST call ApplyFragmentShader soon afterwards.
|
||||
Shader *ApplyVertexShader(int prim, u32 vertType);
|
||||
LinkedShader *ApplyFragmentShader(Shader *vs, int prim, u32 vertType);
|
||||
|
||||
void DirtyShader();
|
||||
void DirtyUniform(u32 what) {
|
||||
globalDirty_ |= what;
|
||||
@@ -192,6 +198,10 @@ private:
|
||||
typedef std::vector<LinkedShaderCacheEntry> LinkedShaderCache;
|
||||
|
||||
LinkedShaderCache linkedShaderCache_;
|
||||
|
||||
FragmentShaderID FSID_;
|
||||
bool lastShaderSame_;
|
||||
|
||||
FragmentShaderID lastFSID_;
|
||||
VertexShaderID lastVSID_;
|
||||
|
||||
|
||||
@@ -526,12 +526,12 @@ void TransformDrawEngine::DoFlush() {
|
||||
GEPrimitiveType prim = prevPrim_;
|
||||
ApplyDrawState(prim);
|
||||
|
||||
LinkedShader *program = shaderManager_->ApplyShader(prim, lastVType_);
|
||||
Shader *vshader = shaderManager_->ApplyVertexShader(prim, lastVType_);
|
||||
|
||||
// Compiler warns about this because it's only used in the #ifdeffed out RangeElements path.
|
||||
int maxIndex = 0;
|
||||
|
||||
if (program->useHWTransform_) {
|
||||
if (vshader->UseHWTransform()) {
|
||||
GLuint vbo = 0, ebo = 0;
|
||||
int vertexCount = 0;
|
||||
bool useElements = true;
|
||||
@@ -699,7 +699,9 @@ rotateVBO:
|
||||
|
||||
VERBOSE_LOG(G3D, "Flush prim %i! %i verts in one go", prim, vertexCount);
|
||||
|
||||
LinkedShader *program = shaderManager_->ApplyFragmentShader(vshader, prim, lastVType_);
|
||||
SetupDecFmtForDraw(program, dec_->GetDecVtxFmt(), vbo ? 0 : decoded);
|
||||
|
||||
if (useElements) {
|
||||
#if 1 // USING_GLES2
|
||||
glDrawElements(glprim[prim], vertexCount, GL_UNSIGNED_SHORT, ebo ? 0 : (GLvoid*)decIndex);
|
||||
@@ -715,6 +717,7 @@ rotateVBO:
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
} else {
|
||||
DecodeVerts();
|
||||
LinkedShader *program = shaderManager_->ApplyFragmentShader(vshader, prim, lastVType_);
|
||||
gpuStats.numUncachedVertsDrawn += indexGen.VertexCount();
|
||||
prim = indexGen.Prim();
|
||||
// Undo the strip optimization, not supported by the SW code yet.
|
||||
|
||||
Reference in new issue
Block a user