Split up ApplyShader into ApplyVertexShader and ApplyFragmentShader.

Will allow the alphatest avoiding optimization later.
This commit is contained in:
Henrik Rydgard committed 2014-03-24 10:55:07 +01:00
1 parent 893a719c4e
commit f2f0355d94
3 files changed
+34 -14

No files matched your search

+18 -11
View File
@@ -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;
}
+11 -1
View File
@@ -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_;
+5 -2
View File
@@ -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.