From 163f81e5be1806cf0efdbddde7d49b6bf969041b Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Wed, 10 Sep 2014 14:07:30 +0200 Subject: [PATCH] DX9: "Linked" shaders are now pointless, so remove them. --- GPU/Directx9/GPU_DX9.cpp | 2 +- GPU/Directx9/ShaderManagerDX9.cpp | 82 +++++---------------------- GPU/Directx9/ShaderManagerDX9.h | 63 ++------------------ GPU/Directx9/TransformPipelineDX9.cpp | 12 ++-- GPU/Directx9/TransformPipelineDX9.h | 6 +- 5 files changed, 31 insertions(+), 134 deletions(-) diff --git a/GPU/Directx9/GPU_DX9.cpp b/GPU/Directx9/GPU_DX9.cpp index bdb2f34a2b..a4188daa31 100644 --- a/GPU/Directx9/GPU_DX9.cpp +++ b/GPU/Directx9/GPU_DX9.cpp @@ -1413,7 +1413,7 @@ void DIRECTX9_GPU::ExecuteOpInternal(u32 op, u32 diff) { void DIRECTX9_GPU::UpdateStats() { gpuStats.numVertexShaders = shaderManager_->NumVertexShaders(); gpuStats.numFragmentShaders = shaderManager_->NumFragmentShaders(); - gpuStats.numShaders = shaderManager_->NumPrograms(); + gpuStats.numShaders = -1; gpuStats.numTextures = (int)textureCache_.NumLoadedTextures(); gpuStats.numFBOs = (int)framebufferManager_.NumVFBs(); } diff --git a/GPU/Directx9/ShaderManagerDX9.cpp b/GPU/Directx9/ShaderManagerDX9.cpp index cf73a321c6..7089530b31 100644 --- a/GPU/Directx9/ShaderManagerDX9.cpp +++ b/GPU/Directx9/ShaderManagerDX9.cpp @@ -45,7 +45,7 @@ PSShader::PSShader(const char *code, bool useHWTransform) : failed_(false), useH bool success; std::string errorMessage; - success = CompilePixelShader(code, &shader, &constant, errorMessage); + success = CompilePixelShader(code, &shader, NULL, errorMessage); if (!errorMessage.empty()) { if (success) { @@ -73,8 +73,6 @@ PSShader::PSShader(const char *code, bool useHWTransform) : failed_(false), useH PSShader::~PSShader() { pD3Ddevice->SetPixelShader(NULL); - if (constant) - constant->Release(); if (shader) shader->Release(); } @@ -87,7 +85,7 @@ VSShader::VSShader(const char *code, int vertType, bool useHWTransform) : failed bool success; std::string errorMessage; - success = CompileVertexShader(code, &shader, &constant, errorMessage); + success = CompileVertexShader(code, &shader, NULL, errorMessage); if (!errorMessage.empty()) { if (success) { @@ -115,41 +113,11 @@ VSShader::VSShader(const char *code, int vertType, bool useHWTransform) : failed VSShader::~VSShader() { pD3Ddevice->SetVertexShader(NULL); - if (constant) - constant->Release(); if (shader) shader->Release(); } -// Helper -D3DXHANDLE PSShader::GetConstantByName(LPCSTR pName) { - return constant->GetConstantByName(NULL, pName); -} - -// Helper -D3DXHANDLE VSShader::GetConstantByName(LPCSTR pName) { - return constant->GetConstantByName(NULL, pName); -} - -LinkedShaderDX9::LinkedShaderDX9(VSShader *vs, PSShader *fs, u32 vertType, bool useHWTransform) - : useHWTransform_(useHWTransform) { - INFO_LOG(G3D, "Linked shader: vs %i fs %i", (int)vs->shader, (int)fs->shader); - - m_vs = vs; - m_fs = fs; - - pD3Ddevice->SetPixelShader(fs->shader); - pD3Ddevice->SetVertexShader(vs->shader); - - // The rest, use the "dirty" mechanism. - use(); -} - -LinkedShaderDX9::~LinkedShaderDX9() { -// glDeleteProgram(program); -} - void ShaderManagerDX9::PSSetColorUniform3(int creg, u32 color) { const float col[4] = { ((color & 0xFF)) / 255.0f, @@ -243,11 +211,6 @@ void ConvertProjMatrixToD3D(Matrix4x4 & in, bool invert) { in = in * s * t; } -void LinkedShaderDX9::use() { - pD3Ddevice->SetPixelShader(m_fs->shader); - pD3Ddevice->SetVertexShader(m_vs->shader); -} - void ShaderManagerDX9::PSUpdateUniforms(int dirtyUniforms) { if (dirtyUniforms & DIRTY_TEXENV) { PSSetColorUniform3(CONST_PS_TEXENV, gstate.texenvcolor); @@ -417,7 +380,7 @@ void ShaderManagerDX9::VSUpdateUniforms(int dirtyUniforms) { } } -ShaderManagerDX9::ShaderManagerDX9() : lastShader_(NULL), globalDirty_(0xFFFFFFFF) { +ShaderManagerDX9::ShaderManagerDX9() : lastVShader_(nullptr), lastPShader_(nullptr), globalDirty_(0xFFFFFFFF) { codeBuffer_ = new char[16384]; } @@ -426,16 +389,12 @@ ShaderManagerDX9::~ShaderManagerDX9() { } void ShaderManagerDX9::Clear() { - for (auto iter = linkedShaderCache_.begin(); iter != linkedShaderCache_.end(); ++iter) { - delete iter->ls; - } for (auto iter = fsCache_.begin(); iter != fsCache_.end(); ++iter) { delete iter->second; } for (auto iter = vsCache_.begin(); iter != vsCache_.end(); ++iter) { delete iter->second; } - linkedShaderCache_.clear(); fsCache_.clear(); vsCache_.clear(); globalDirty_ = 0xFFFFFFFF; @@ -453,16 +412,18 @@ void ShaderManagerDX9::DirtyShader() { // Forget the last shader ID lastFSID_.clear(); lastVSID_.clear(); - lastShader_ = 0; + lastVShader_ = 0; + lastPShader_ = 0; globalDirty_ = 0xFFFFFFFF; } void ShaderManagerDX9::DirtyLastShader() { // disables vertex arrays - lastShader_ = 0; + lastVShader_ = 0; + lastPShader_ = 0; } -LinkedShaderDX9 *ShaderManagerDX9::ApplyShader(int prim, u32 vertType) { +VSShader *ShaderManagerDX9::ApplyShader(int prim, u32 vertType) { if (globalDirty_) { PSUpdateUniforms(globalDirty_); VSUpdateUniforms(globalDirty_); @@ -477,8 +438,8 @@ LinkedShaderDX9 *ShaderManagerDX9::ApplyShader(int prim, u32 vertType) { ComputeFragmentShaderIDDX9(&FSID); // Just update uniforms if this is the same shader as last time. - if (lastShader_ != 0 && VSID == lastVSID_ && FSID == lastFSID_) { - return lastShader_; // Already all set. + if (lastVShader_ != nullptr && lastPShader_ != nullptr && VSID == lastVSID_ && FSID == lastFSID_) { + return lastVShader_; // Already all set. } lastVSID_ = VSID; @@ -521,25 +482,12 @@ LinkedShaderDX9 *ShaderManagerDX9::ApplyShader(int prim, u32 vertType) { fs = fsIter->second; } - // Okay, we have both shaders. Let's see if there's a linked one. - LinkedShaderDX9 *ls = NULL; + pD3Ddevice->SetPixelShader(fs->shader); + pD3Ddevice->SetVertexShader(vs->shader); - for (auto iter = linkedShaderCache_.begin(); iter != linkedShaderCache_.end(); ++iter) { - if (iter->vs == vs && iter->fs == fs) { - ls = iter->ls; - } - } - - if (ls == NULL) { - ls = new LinkedShaderDX9(vs, fs, vertType, vs->UseHWTransform()); // This does "use" automatically - const LinkedShaderCacheEntry entry(vs, fs, ls); - linkedShaderCache_.push_back(entry); - } else { - ls->use(); - } - - lastShader_ = ls; - return ls; + lastPShader_ = fs; + lastVShader_ = vs; + return vs; } } // namespace diff --git a/GPU/Directx9/ShaderManagerDX9.h b/GPU/Directx9/ShaderManagerDX9.h index 167d08228e..3f4dac4ef5 100644 --- a/GPU/Directx9/ShaderManagerDX9.h +++ b/GPU/Directx9/ShaderManagerDX9.h @@ -29,38 +29,11 @@ namespace DX9 { class PSShader; class VSShader; + void ConvertProjMatrixToD3D(Matrix4x4 & in); -// Pre-fetched attrs and uniforms +// Pretty much full. Will need more bits for more fine grained dirty tracking for lights. enum { - ATTR_POSITION = 0, - ATTR_TEXCOORD = 1, - ATTR_NORMAL = 2, - ATTR_W1 = 3, - ATTR_W2 = 4, - ATTR_COLOR0 = 5, - ATTR_COLOR1 = 6, - - ATTR_COUNT, -}; - -class LinkedShaderDX9 { -public: - LinkedShaderDX9(VSShader *vs, PSShader *fs, u32 vertType, bool useHWTransform); - ~LinkedShaderDX9(); - - void use(); - - // Set to false if the VS failed, happens on Mali-400 a lot for complex shaders. - bool useHWTransform_; - - VSShader *m_vs; - PSShader *m_fs; -}; - -// Will reach 32 bits soon :P -enum -{ DIRTY_PROJMATRIX = (1 << 0), DIRTY_PROJTHROUGHMATRIX = (1 << 1), DIRTY_FOGCOLOR = (1 << 2), @@ -94,13 +67,6 @@ enum DIRTY_BONEMATRIX6 = (1 << 30), DIRTY_BONEMATRIX7 = (1 << 31), - DIRTY_VSHADER_UNIFORMS = DIRTY_PROJMATRIX | DIRTY_PROJTHROUGHMATRIX | DIRTY_FOGCOEF | DIRTY_LIGHT0 | DIRTY_LIGHT1 | DIRTY_LIGHT2 | DIRTY_LIGHT3 | - DIRTY_MATDIFFUSE | DIRTY_MATSPECULAR | DIRTY_MATEMISSIVE | DIRTY_AMBIENT | DIRTY_MATAMBIENTALPHA | DIRTY_MATERIAL | DIRTY_UVSCALEOFFSET | - DIRTY_WORLDMATRIX | DIRTY_VIEWMATRIX | DIRTY_TEXMATRIX | - DIRTY_BONEMATRIX0 | DIRTY_BONEMATRIX1 | DIRTY_BONEMATRIX2 | DIRTY_BONEMATRIX3 | DIRTY_BONEMATRIX4 | DIRTY_BONEMATRIX5 | DIRTY_BONEMATRIX6 | DIRTY_BONEMATRIX7, - - DIRTY_PSHADER_UNIFORMS = DIRTY_FOGCOLOR | DIRTY_TEXENV | DIRTY_ALPHACOLORREF | DIRTY_ALPHACOLORMASK, - DIRTY_ALL = 0xFFFFFFFF }; @@ -116,10 +82,7 @@ public: bool Failed() const { return failed_; } bool UseHWTransform() const { return useHWTransform_; } - D3DXHANDLE GetConstantByName(LPCSTR pName); - LPDIRECT3DPIXELSHADER9 shader; - LPD3DXCONSTANTTABLE constant; protected: std::string source_; @@ -137,10 +100,7 @@ public: bool Failed() const { return failed_; } bool UseHWTransform() const { return useHWTransform_; } - D3DXHANDLE GetConstantByName(LPCSTR pName); - LPDIRECT3DVERTEXSHADER9 shader; - LPD3DXCONSTANTTABLE constant; protected: std::string source_; @@ -155,7 +115,7 @@ public: ~ShaderManagerDX9(); void ClearCache(bool deleteThem); // TODO: deleteThem currently not respected - LinkedShaderDX9 *ApplyShader(int prim, u32 vertType); + VSShader *ApplyShader(int prim, u32 vertType); void DirtyShader(); void DirtyUniform(u32 what) { globalDirty_ |= what; @@ -164,7 +124,6 @@ public: int NumVertexShaders() const { return (int)vsCache_.size(); } int NumFragmentShaders() const { return (int)fsCache_.size(); } - int NumPrograms() const { return (int)linkedShaderCache_.size(); } private: void PSUpdateUniforms(int dirtyUniforms); @@ -183,25 +142,15 @@ private: void Clear(); - struct LinkedShaderCacheEntry { - LinkedShaderCacheEntry(VSShader *vs_, PSShader *fs_, LinkedShaderDX9 *ls_) - : vs(vs_), fs(fs_), ls(ls_) { } - - VSShader *vs; - PSShader *fs; - LinkedShaderDX9 *ls; - - }; - typedef std::vector LinkedShaderCache; - - LinkedShaderCache linkedShaderCache_; FragmentShaderIDDX9 lastFSID_; VertexShaderIDDX9 lastVSID_; - LinkedShaderDX9 *lastShader_; u32 globalDirty_; char *codeBuffer_; + VSShader *lastVShader_; + PSShader *lastPShader_; + typedef std::map FSCache; FSCache fsCache_; diff --git a/GPU/Directx9/TransformPipelineDX9.cpp b/GPU/Directx9/TransformPipelineDX9.cpp index ebf3cc3986..de16227267 100644 --- a/GPU/Directx9/TransformPipelineDX9.cpp +++ b/GPU/Directx9/TransformPipelineDX9.cpp @@ -271,7 +271,7 @@ static void LogDecFmtForDraw(const DecVtxFormat &decFmt) { //pD3Ddevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); } -IDirect3DVertexDeclaration9 *TransformDrawEngineDX9::SetupDecFmtForDraw(LinkedShaderDX9 *program, const DecVtxFormat &decFmt, u32 pspFmt) { +IDirect3DVertexDeclaration9 *TransformDrawEngineDX9::SetupDecFmtForDraw(VSShader *vshader, const DecVtxFormat &decFmt, u32 pspFmt) { auto vertexDeclCached = vertexDeclMap_.find(pspFmt); if (vertexDeclCached == vertexDeclMap_.end()) { @@ -437,7 +437,7 @@ bool TransformDrawEngineDX9::IsReallyAClear(int numVerts) const { // Actually again, single quads could be drawn more efficiently using GL_TRIANGLE_STRIP, no need to duplicate verts as for // GL_TRIANGLES. Still need to sw transform to compute the extra two corners though. void TransformDrawEngineDX9::SoftwareTransformAndDraw( - int prim, u8 *decoded, LinkedShaderDX9 *program, int vertexCount, u32 vertType, void *inds, int indexType, const DecVtxFormat &decVtxFormat, int maxIndex) { + int prim, u8 *decoded, int vertexCount, u32 vertType, void *inds, int indexType, const DecVtxFormat &decVtxFormat, int maxIndex) { bool throughmode = (vertType & GE_VTYPE_THROUGH_MASK) != 0; bool lmode = gstate.isUsingSecondaryColor() && gstate.isLightingEnabled(); @@ -1057,9 +1057,9 @@ void TransformDrawEngineDX9::DoFlush() { GEPrimitiveType prim = prevPrim_; ApplyDrawState(prim); - LinkedShaderDX9 *program = shaderManager_->ApplyShader(prim, lastVType_); + VSShader *vshader = shaderManager_->ApplyShader(prim, lastVType_); - if (program->useHWTransform_) { + if (vshader->UseHWTransform()) { LPDIRECT3DVERTEXBUFFER9 vb_ = NULL; LPDIRECT3DINDEXBUFFER9 ib_ = NULL; @@ -1233,7 +1233,7 @@ rotateVBO: gstate_c.vertexFullAlpha = gstate_c.vertexFullAlpha && ((hasColor && (gstate.materialupdate & 1)) || gstate.getMaterialAmbientA() == 255) && (!gstate.isLightingEnabled() || gstate.getAmbientA() == 255); } - IDirect3DVertexDeclaration9 *pHardwareVertexDecl = SetupDecFmtForDraw(program, dec_->GetDecVtxFmt(), dec_->VertexType()); + IDirect3DVertexDeclaration9 *pHardwareVertexDecl = SetupDecFmtForDraw(vshader, dec_->GetDecVtxFmt(), dec_->VertexType()); if (pHardwareVertexDecl) { pD3Ddevice->SetVertexDeclaration(pHardwareVertexDecl); @@ -1272,7 +1272,7 @@ rotateVBO: DEBUG_LOG(G3D, "Flush prim %i SW! %i verts in one go", prim, indexGen.VertexCount()); SoftwareTransformAndDraw( - prim, decoded, program, indexGen.VertexCount(), + prim, decoded, indexGen.VertexCount(), dec_->VertexType(), (void *)decIndex, GE_VTYPE_IDX_16BIT, dec_->GetDecVtxFmt(), indexGen.MaxIndex()); } diff --git a/GPU/Directx9/TransformPipelineDX9.h b/GPU/Directx9/TransformPipelineDX9.h index 5a83b8e137..665f08b2f2 100644 --- a/GPU/Directx9/TransformPipelineDX9.h +++ b/GPU/Directx9/TransformPipelineDX9.h @@ -28,7 +28,7 @@ struct DecVtxFormat; namespace DX9 { -class LinkedShaderDX9; +class VSShader; class ShaderManagerDX9; class TextureCacheDX9; class FramebufferManagerDX9; @@ -144,10 +144,10 @@ public: private: void DoFlush(); - void SoftwareTransformAndDraw(int prim, u8 *decoded, LinkedShaderDX9 *program, int vertexCount, u32 vertexType, void *inds, int indexType, const DecVtxFormat &decVtxFormat, int maxIndex); + void SoftwareTransformAndDraw(int prim, u8 *decoded, int vertexCount, u32 vertexType, void *inds, int indexType, const DecVtxFormat &decVtxFormat, int maxIndex); void ApplyDrawState(int prim); bool IsReallyAClear(int numVerts) const; - IDirect3DVertexDeclaration9 *SetupDecFmtForDraw(LinkedShaderDX9 *program, const DecVtxFormat &decFmt, u32 pspFmt); + IDirect3DVertexDeclaration9 *SetupDecFmtForDraw(VSShader *vshader, const DecVtxFormat &decFmt, u32 pspFmt); // Preprocessing for spline/bezier u32 NormalizeVertices(u8 *outPtr, u8 *bufPtr, const u8 *inPtr, VertexDecoderDX9 *dec, int lowerBound, int upperBound, u32 vertType);