DX9: "Linked" shaders are now pointless, so remove them.

This commit is contained in:
Henrik Rydgard 2014-09-10 14:07:30 +02:00
parent 0dc6150a2e
commit 163f81e5be
5 changed files with 31 additions and 134 deletions

View file

@ -1413,7 +1413,7 @@ void DIRECTX9_GPU::ExecuteOpInternal(u32 op, u32 diff) {
void DIRECTX9_GPU::UpdateStats() { void DIRECTX9_GPU::UpdateStats() {
gpuStats.numVertexShaders = shaderManager_->NumVertexShaders(); gpuStats.numVertexShaders = shaderManager_->NumVertexShaders();
gpuStats.numFragmentShaders = shaderManager_->NumFragmentShaders(); gpuStats.numFragmentShaders = shaderManager_->NumFragmentShaders();
gpuStats.numShaders = shaderManager_->NumPrograms(); gpuStats.numShaders = -1;
gpuStats.numTextures = (int)textureCache_.NumLoadedTextures(); gpuStats.numTextures = (int)textureCache_.NumLoadedTextures();
gpuStats.numFBOs = (int)framebufferManager_.NumVFBs(); gpuStats.numFBOs = (int)framebufferManager_.NumVFBs();
} }

View file

@ -45,7 +45,7 @@ PSShader::PSShader(const char *code, bool useHWTransform) : failed_(false), useH
bool success; bool success;
std::string errorMessage; std::string errorMessage;
success = CompilePixelShader(code, &shader, &constant, errorMessage); success = CompilePixelShader(code, &shader, NULL, errorMessage);
if (!errorMessage.empty()) { if (!errorMessage.empty()) {
if (success) { if (success) {
@ -73,8 +73,6 @@ PSShader::PSShader(const char *code, bool useHWTransform) : failed_(false), useH
PSShader::~PSShader() { PSShader::~PSShader() {
pD3Ddevice->SetPixelShader(NULL); pD3Ddevice->SetPixelShader(NULL);
if (constant)
constant->Release();
if (shader) if (shader)
shader->Release(); shader->Release();
} }
@ -87,7 +85,7 @@ VSShader::VSShader(const char *code, int vertType, bool useHWTransform) : failed
bool success; bool success;
std::string errorMessage; std::string errorMessage;
success = CompileVertexShader(code, &shader, &constant, errorMessage); success = CompileVertexShader(code, &shader, NULL, errorMessage);
if (!errorMessage.empty()) { if (!errorMessage.empty()) {
if (success) { if (success) {
@ -115,41 +113,11 @@ VSShader::VSShader(const char *code, int vertType, bool useHWTransform) : failed
VSShader::~VSShader() { VSShader::~VSShader() {
pD3Ddevice->SetVertexShader(NULL); pD3Ddevice->SetVertexShader(NULL);
if (constant)
constant->Release();
if (shader) if (shader)
shader->Release(); 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) { void ShaderManagerDX9::PSSetColorUniform3(int creg, u32 color) {
const float col[4] = { const float col[4] = {
((color & 0xFF)) / 255.0f, ((color & 0xFF)) / 255.0f,
@ -243,11 +211,6 @@ void ConvertProjMatrixToD3D(Matrix4x4 & in, bool invert) {
in = in * s * t; in = in * s * t;
} }
void LinkedShaderDX9::use() {
pD3Ddevice->SetPixelShader(m_fs->shader);
pD3Ddevice->SetVertexShader(m_vs->shader);
}
void ShaderManagerDX9::PSUpdateUniforms(int dirtyUniforms) { void ShaderManagerDX9::PSUpdateUniforms(int dirtyUniforms) {
if (dirtyUniforms & DIRTY_TEXENV) { if (dirtyUniforms & DIRTY_TEXENV) {
PSSetColorUniform3(CONST_PS_TEXENV, gstate.texenvcolor); 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]; codeBuffer_ = new char[16384];
} }
@ -426,16 +389,12 @@ ShaderManagerDX9::~ShaderManagerDX9() {
} }
void ShaderManagerDX9::Clear() { void ShaderManagerDX9::Clear() {
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; delete iter->second;
} }
for (auto iter = vsCache_.begin(); iter != vsCache_.end(); ++iter) { for (auto iter = vsCache_.begin(); iter != vsCache_.end(); ++iter) {
delete iter->second; delete iter->second;
} }
linkedShaderCache_.clear();
fsCache_.clear(); fsCache_.clear();
vsCache_.clear(); vsCache_.clear();
globalDirty_ = 0xFFFFFFFF; globalDirty_ = 0xFFFFFFFF;
@ -453,16 +412,18 @@ void ShaderManagerDX9::DirtyShader() {
// Forget the last shader ID // Forget the last shader ID
lastFSID_.clear(); lastFSID_.clear();
lastVSID_.clear(); lastVSID_.clear();
lastShader_ = 0; lastVShader_ = 0;
lastPShader_ = 0;
globalDirty_ = 0xFFFFFFFF; globalDirty_ = 0xFFFFFFFF;
} }
void ShaderManagerDX9::DirtyLastShader() { // disables vertex arrays 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_) { if (globalDirty_) {
PSUpdateUniforms(globalDirty_); PSUpdateUniforms(globalDirty_);
VSUpdateUniforms(globalDirty_); VSUpdateUniforms(globalDirty_);
@ -477,8 +438,8 @@ LinkedShaderDX9 *ShaderManagerDX9::ApplyShader(int prim, u32 vertType) {
ComputeFragmentShaderIDDX9(&FSID); ComputeFragmentShaderIDDX9(&FSID);
// Just update uniforms if this is the same shader as last time. // Just update uniforms if this is the same shader as last time.
if (lastShader_ != 0 && VSID == lastVSID_ && FSID == lastFSID_) { if (lastVShader_ != nullptr && lastPShader_ != nullptr && VSID == lastVSID_ && FSID == lastFSID_) {
return lastShader_; // Already all set. return lastVShader_; // Already all set.
} }
lastVSID_ = VSID; lastVSID_ = VSID;
@ -521,25 +482,12 @@ LinkedShaderDX9 *ShaderManagerDX9::ApplyShader(int prim, u32 vertType) {
fs = fsIter->second; fs = fsIter->second;
} }
// Okay, we have both shaders. Let's see if there's a linked one. pD3Ddevice->SetPixelShader(fs->shader);
LinkedShaderDX9 *ls = NULL; pD3Ddevice->SetVertexShader(vs->shader);
for (auto iter = linkedShaderCache_.begin(); iter != linkedShaderCache_.end(); ++iter) { lastPShader_ = fs;
if (iter->vs == vs && iter->fs == fs) { lastVShader_ = vs;
ls = iter->ls; return vs;
}
}
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;
} }
} // namespace } // namespace

View file

@ -29,38 +29,11 @@ namespace DX9 {
class PSShader; class PSShader;
class VSShader; class VSShader;
void ConvertProjMatrixToD3D(Matrix4x4 & in); 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 { 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_PROJMATRIX = (1 << 0),
DIRTY_PROJTHROUGHMATRIX = (1 << 1), DIRTY_PROJTHROUGHMATRIX = (1 << 1),
DIRTY_FOGCOLOR = (1 << 2), DIRTY_FOGCOLOR = (1 << 2),
@ -94,13 +67,6 @@ enum
DIRTY_BONEMATRIX6 = (1 << 30), DIRTY_BONEMATRIX6 = (1 << 30),
DIRTY_BONEMATRIX7 = (1 << 31), 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 DIRTY_ALL = 0xFFFFFFFF
}; };
@ -116,10 +82,7 @@ public:
bool Failed() const { return failed_; } bool Failed() const { return failed_; }
bool UseHWTransform() const { return useHWTransform_; } bool UseHWTransform() const { return useHWTransform_; }
D3DXHANDLE GetConstantByName(LPCSTR pName);
LPDIRECT3DPIXELSHADER9 shader; LPDIRECT3DPIXELSHADER9 shader;
LPD3DXCONSTANTTABLE constant;
protected: protected:
std::string source_; std::string source_;
@ -137,10 +100,7 @@ public:
bool Failed() const { return failed_; } bool Failed() const { return failed_; }
bool UseHWTransform() const { return useHWTransform_; } bool UseHWTransform() const { return useHWTransform_; }
D3DXHANDLE GetConstantByName(LPCSTR pName);
LPDIRECT3DVERTEXSHADER9 shader; LPDIRECT3DVERTEXSHADER9 shader;
LPD3DXCONSTANTTABLE constant;
protected: protected:
std::string source_; std::string source_;
@ -155,7 +115,7 @@ public:
~ShaderManagerDX9(); ~ShaderManagerDX9();
void ClearCache(bool deleteThem); // TODO: deleteThem currently not respected void ClearCache(bool deleteThem); // TODO: deleteThem currently not respected
LinkedShaderDX9 *ApplyShader(int prim, u32 vertType); VSShader *ApplyShader(int prim, u32 vertType);
void DirtyShader(); void DirtyShader();
void DirtyUniform(u32 what) { void DirtyUniform(u32 what) {
globalDirty_ |= what; globalDirty_ |= what;
@ -164,7 +124,6 @@ public:
int NumVertexShaders() const { return (int)vsCache_.size(); } int NumVertexShaders() const { return (int)vsCache_.size(); }
int NumFragmentShaders() const { return (int)fsCache_.size(); } int NumFragmentShaders() const { return (int)fsCache_.size(); }
int NumPrograms() const { return (int)linkedShaderCache_.size(); }
private: private:
void PSUpdateUniforms(int dirtyUniforms); void PSUpdateUniforms(int dirtyUniforms);
@ -183,25 +142,15 @@ private:
void Clear(); 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<LinkedShaderCacheEntry> LinkedShaderCache;
LinkedShaderCache linkedShaderCache_;
FragmentShaderIDDX9 lastFSID_; FragmentShaderIDDX9 lastFSID_;
VertexShaderIDDX9 lastVSID_; VertexShaderIDDX9 lastVSID_;
LinkedShaderDX9 *lastShader_;
u32 globalDirty_; u32 globalDirty_;
char *codeBuffer_; char *codeBuffer_;
VSShader *lastVShader_;
PSShader *lastPShader_;
typedef std::map<FragmentShaderIDDX9, PSShader *> FSCache; typedef std::map<FragmentShaderIDDX9, PSShader *> FSCache;
FSCache fsCache_; FSCache fsCache_;

View file

@ -271,7 +271,7 @@ static void LogDecFmtForDraw(const DecVtxFormat &decFmt) {
//pD3Ddevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); //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); auto vertexDeclCached = vertexDeclMap_.find(pspFmt);
if (vertexDeclCached == vertexDeclMap_.end()) { 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 // 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. // GL_TRIANGLES. Still need to sw transform to compute the extra two corners though.
void TransformDrawEngineDX9::SoftwareTransformAndDraw( 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 throughmode = (vertType & GE_VTYPE_THROUGH_MASK) != 0;
bool lmode = gstate.isUsingSecondaryColor() && gstate.isLightingEnabled(); bool lmode = gstate.isUsingSecondaryColor() && gstate.isLightingEnabled();
@ -1057,9 +1057,9 @@ void TransformDrawEngineDX9::DoFlush() {
GEPrimitiveType prim = prevPrim_; GEPrimitiveType prim = prevPrim_;
ApplyDrawState(prim); ApplyDrawState(prim);
LinkedShaderDX9 *program = shaderManager_->ApplyShader(prim, lastVType_); VSShader *vshader = shaderManager_->ApplyShader(prim, lastVType_);
if (program->useHWTransform_) { if (vshader->UseHWTransform()) {
LPDIRECT3DVERTEXBUFFER9 vb_ = NULL; LPDIRECT3DVERTEXBUFFER9 vb_ = NULL;
LPDIRECT3DINDEXBUFFER9 ib_ = 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); 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) { if (pHardwareVertexDecl) {
pD3Ddevice->SetVertexDeclaration(pHardwareVertexDecl); pD3Ddevice->SetVertexDeclaration(pHardwareVertexDecl);
@ -1272,7 +1272,7 @@ rotateVBO:
DEBUG_LOG(G3D, "Flush prim %i SW! %i verts in one go", prim, indexGen.VertexCount()); DEBUG_LOG(G3D, "Flush prim %i SW! %i verts in one go", prim, indexGen.VertexCount());
SoftwareTransformAndDraw( SoftwareTransformAndDraw(
prim, decoded, program, indexGen.VertexCount(), prim, decoded, indexGen.VertexCount(),
dec_->VertexType(), (void *)decIndex, GE_VTYPE_IDX_16BIT, dec_->GetDecVtxFmt(), dec_->VertexType(), (void *)decIndex, GE_VTYPE_IDX_16BIT, dec_->GetDecVtxFmt(),
indexGen.MaxIndex()); indexGen.MaxIndex());
} }

View file

@ -28,7 +28,7 @@ struct DecVtxFormat;
namespace DX9 { namespace DX9 {
class LinkedShaderDX9; class VSShader;
class ShaderManagerDX9; class ShaderManagerDX9;
class TextureCacheDX9; class TextureCacheDX9;
class FramebufferManagerDX9; class FramebufferManagerDX9;
@ -144,10 +144,10 @@ public:
private: private:
void DoFlush(); 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); void ApplyDrawState(int prim);
bool IsReallyAClear(int numVerts) const; 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 // Preprocessing for spline/bezier
u32 NormalizeVertices(u8 *outPtr, u8 *bufPtr, const u8 *inPtr, VertexDecoderDX9 *dec, int lowerBound, int upperBound, u32 vertType); u32 NormalizeVertices(u8 *outPtr, u8 *bufPtr, const u8 *inPtr, VertexDecoderDX9 *dec, int lowerBound, int upperBound, u32 vertType);