00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef __CS_SHADERPLUGINS_COMMON_SHADERPROGRAM_H__
00021 #define __CS_SHADERPLUGINS_COMMON_SHADERPROGRAM_H__
00022
00027 #include "csextern.h"
00028 #include "csgfx/shadervararrayhelper.h"
00029 #include "csutil/array.h"
00030 #include "csutil/dirtyaccessarray.h"
00031 #include "csutil/leakguard.h"
00032 #include "csutil/ref.h"
00033 #include "csutil/scf_implementation.h"
00034 #include "csutil/strhash.h"
00035 #include "imap/services.h"
00036 #include "iutil/document.h"
00037 #include "iutil/strset.h"
00038 #include "iutil/vfs.h"
00039
00040 #include "csplugincommon/shader/shaderplugin.h"
00041
00042 struct iDataBuffer;
00043 struct iObjectRegistry;
00044
00045
00046
00047
00048
00049
00050 #define CS_TOKEN_LIST_TOKEN(x)
00051 #include "csplugincommon/shader/shaderprogram.tok"
00052 #undef CS_TOKEN_LIST_TOKEN
00053
00061 class CS_CRYSTALSPACE_EXPORT csShaderProgram :
00062 public scfImplementation2<csShaderProgram,
00063 iShaderProgram,
00064 iShaderDestinationResolver>
00065 {
00066 protected:
00067 csStringHash commonTokens;
00068 #define CS_INIT_TOKEN_TABLE_NAME InitCommonTokens
00069 #define CS_TOKEN_ITEM_FILE \
00070 "csplugincommon/shader/shaderprogram.tok"
00071 #include "cstool/tokenlist.h"
00072 #undef CS_TOKEN_ITEM_FILE
00073 #undef CS_INIT_TOKEN_TABLE_NAME
00074
00075 protected:
00076 iObjectRegistry* objectReg;
00077 csRef<iSyntaxService> synsrv;
00078 csRef<iShaderVarStringSet> stringsSvName;
00079
00080 public:
00084 enum ProgramParamType
00085 {
00086 ParamInvalid = 0,
00087 ParamInt = 0x0001,
00088 ParamFloat = 0x0002,
00089 ParamVector2 = 0x0004,
00090 ParamVector3 = 0x0008,
00091 ParamVector4 = 0x0010,
00092 ParamMatrix = 0x0020,
00093 ParamTransform = 0x0040,
00094 ParamArray = 0x0080,
00095 ParamShaderExp = 0x0100,
00096
00097 ParamVector = ParamInt | ParamFloat | ParamVector2 | ParamVector3 | ParamVector4
00098 };
00099
00103 struct CS_CRYSTALSPACE_EXPORT ProgramParam
00104 {
00105 bool valid;
00106
00107
00108 CS::ShaderVarStringID name;
00109 csDirtyAccessArray<size_t, csArrayElementHandler<size_t>,
00110 CS::Memory::LocalBufferAllocator<size_t, 2,
00111 CS::Memory::AllocatorMalloc, true> > indices;
00112
00113 csRef<csShaderVariable> var;
00114
00115 ProgramParam() : valid (false), name (CS::InvalidShaderVarStringID) { }
00117 bool IsConstant() const
00118 { return valid && var.IsValid() && (var->GetAccessor() == 0); }
00119
00121
00122 void SetValue (float val);
00123 void SetValue (const csVector4& val);
00125 };
00126
00127 class CS_CRYSTALSPACE_EXPORT ProgramParamParser
00128 {
00129 iSyntaxService* synsrv;
00130 iShaderVarStringSet* stringsSvName;
00131 public:
00132 ProgramParamParser (iSyntaxService* synsrv,
00133 iShaderVarStringSet* stringsSvName) : synsrv (synsrv),
00134 stringsSvName (stringsSvName) {}
00135
00143 bool ParseProgramParam (iDocumentNode* node,
00144 ProgramParam& param, uint types = ~0);
00145 };
00146
00147 protected:
00152 bool ParseProgramParam (iDocumentNode* node,
00153 ProgramParam& param, uint types = ~0)
00154 {
00155 ProgramParamParser parser (synsrv, stringsSvName);
00156 return parser.ParseProgramParam (node, param, types);
00157 }
00158
00162 struct VariableMapEntry : public csShaderVarMapping
00163 {
00164 ProgramParam mappingParam;
00165 intptr_t userVal;
00166
00167 VariableMapEntry (CS::ShaderVarStringID s, const char* d) :
00168 csShaderVarMapping (s, d)
00169 {
00170 userVal = 0;
00171 mappingParam.name = s;
00172 mappingParam.valid = true;
00173 }
00174 VariableMapEntry (const csShaderVarMapping& other) :
00175 csShaderVarMapping (other.name, other.destination)
00176 {
00177 userVal = 0;
00178 mappingParam.name = other.name;
00179 mappingParam.valid = true;
00180 }
00181 };
00183 csSafeCopyArray<VariableMapEntry> variablemap;
00184
00185 void TryAddUsedShaderVarName (CS::ShaderVarStringID name, csBitArray& bits) const
00186 {
00187 if (name != CS::InvalidShaderVarStringID)
00188 {
00189 if (bits.GetSize() > name) bits.SetBit (name);
00190 }
00191 }
00192 void TryAddUsedShaderVarProgramParam (const ProgramParam& param,
00193 csBitArray& bits) const
00194 {
00195 if (param.valid)
00196 {
00197 TryAddUsedShaderVarName (param.name, bits);
00198 }
00199 }
00200 void GetUsedShaderVarsFromVariableMappings (csBitArray& bits) const;
00201
00203 csString description;
00204
00206 csRef<iDocumentNode> programNode;
00208 csRef<iFile> programFile;
00209
00211 csString programFileName;
00212
00217 bool doVerbose;
00218
00220 bool ParseCommon (iDocumentNode* child);
00222 iDocumentNode* GetProgramNode ();
00224 csPtr<iDataBuffer> GetProgramData ();
00225
00227 void DumpProgramInfo (csString& output);
00229 void DumpVariableMappings (csString& output);
00230
00234 inline csShaderVariable* GetParamSV (const csShaderVariableStack& stack,
00235 const ProgramParam ¶m)
00236 {
00237 csShaderVariable* var = 0;
00238
00239 var = csGetShaderVariableFromStack (stack, param.name);
00240 if (var)
00241 var = CS::Graphics::ShaderVarArrayHelper::GetArrayItem (var,
00242 param.indices.GetArray(), param.indices.GetSize(),
00243 CS::Graphics::ShaderVarArrayHelper::maFail);
00244 if (!var)
00245 var = param.var;
00246
00247 return var;
00248 }
00250
00254 inline bool GetParamVectorVal (const csShaderVariableStack& stack,
00255 const ProgramParam ¶m, csVector4* result)
00256 {
00257 csShaderVariable* var (GetParamSV (stack, param));
00258
00259
00260 if (!var)
00261 return false;
00262
00263 var->GetValue (*result);
00264 return true;
00265 }
00266 inline csVector4 GetParamVectorVal (const csShaderVariableStack& stack,
00267 const ProgramParam ¶m, const csVector4& defVal)
00268 {
00269 csVector4 v;
00270 if (!GetParamVectorVal (stack, param, &v)) return defVal;
00271 return v;
00272 }
00273
00274 inline bool GetParamTransformVal (const csShaderVariableStack& stack,
00275 const ProgramParam ¶m, csReversibleTransform* result)
00276 {
00277 csShaderVariable* var (GetParamSV (stack, param));
00278
00279
00280 if (!var)
00281 return false;
00282
00283 var->GetValue (*result);
00284 return true;
00285 }
00286 inline csReversibleTransform GetParamTransformVal (const csShaderVariableStack& stack,
00287 const ProgramParam ¶m, const csReversibleTransform& defVal)
00288 {
00289 csReversibleTransform t;
00290 if (!GetParamTransformVal (stack, param, &t)) return defVal;
00291 return t;
00292 }
00293
00294 inline bool GetParamFloatVal (const csShaderVariableStack& stack,
00295 const ProgramParam ¶m, float* result)
00296 {
00297 csShaderVariable* var (GetParamSV (stack, param));
00298
00299
00300 if (!var)
00301 return false;
00302
00303 var->GetValue (*result);
00304 return true;
00305 }
00306 inline float GetParamFloatVal (const csShaderVariableStack& stack,
00307 const ProgramParam ¶m, float defVal)
00308 {
00309 float f;
00310 if (!GetParamFloatVal (stack, param, &f)) return defVal;
00311 return f;
00312 }
00314 public:
00315 CS_LEAKGUARD_DECLARE (csShaderProgram);
00316
00317 csShaderProgram (iObjectRegistry* objectReg);
00318 virtual ~csShaderProgram ();
00319
00320 virtual int ResolveTU (const char* )
00321 { return -1; }
00322
00323 virtual csVertexAttrib ResolveBufferDestination (const char* )
00324 { return CS_VATTRIB_INVALID; }
00325
00326 virtual void GetUsedShaderVars (csBitArray& bits) const;
00327
00328
00329
00330 virtual iShaderProgram::CacheLoadResult LoadFromCache (
00331 iHierarchicalCache* cache, iBase* previous, iDocumentNode* programNode,
00332 csRef<iString>* failReason = 0, csRef<iString>* = 0);
00333 };
00334
00337 #endif // __CS_SHADERPLUGINS_COMMON_SHADERPROGRAM_H__