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() {
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();
}

View file

@ -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

View file

@ -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<LinkedShaderCacheEntry> LinkedShaderCache;
LinkedShaderCache linkedShaderCache_;
FragmentShaderIDDX9 lastFSID_;
VertexShaderIDDX9 lastVSID_;
LinkedShaderDX9 *lastShader_;
u32 globalDirty_;
char *codeBuffer_;
VSShader *lastVShader_;
PSShader *lastPShader_;
typedef std::map<FragmentShaderIDDX9, PSShader *> FSCache;
FSCache fsCache_;

View file

@ -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());
}

View file

@ -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);