00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef __CS_IVIDEO_SHADER_H__
00022 #define __CS_IVIDEO_SHADER_H__
00023
00028 #include "csutil/scf.h"
00029
00030 #include "iutil/array.h"
00031
00032 #include "csgfx/shadervar.h"
00033 #include "csutil/array.h"
00034 #include "csutil/bitarray.h"
00035 #include "csutil/refarr.h"
00036 #include "csutil/set.h"
00037 #include "csutil/strset.h"
00038 #include "csutil/noncopyable.h"
00039
00040 struct iDocumentNode;
00041 struct iHierarchicalCache;
00042 struct iLight;
00043 struct iObject;
00044 struct iLoaderContext;
00045 struct iString;
00046
00047 namespace CS
00048 {
00049 namespace Graphics
00050 {
00051 struct RenderMesh;
00052 }
00053 }
00054 class csShaderVariable;
00055
00056 struct iShader;
00057 struct iShaderCompiler;
00058 struct iShaderManager;
00059
00061
00065 class csShaderVariableStack
00066 {
00067 public:
00069 csShaderVariableStack ()
00070 : varArray (0), size (0), ownArray (false)
00071 {}
00072
00079 csShaderVariableStack (const csShaderVariableStack& other)
00080 : size (other.size), ownArray (false)
00081 {
00082 if (other.ownArray)
00083 {
00084 Setup (size);
00085 memcpy (varArray, other.varArray, size * sizeof (csShaderVariable*));
00086 }
00087 else
00088 {
00089 varArray = other.varArray;
00090 }
00091 }
00092
00094 csShaderVariableStack (csShaderVariable** va, size_t size)
00095 : varArray (va), size (size), ownArray (false)
00096 {}
00097
00098 ~csShaderVariableStack ()
00099 {
00100 if (ownArray)
00101 cs_free (varArray);
00102 }
00103
00111 csShaderVariableStack& operator= (const csShaderVariableStack& other)
00112 {
00113 if (other.ownArray)
00114 {
00115 Setup (size);
00116 memcpy (varArray, other.varArray, size * sizeof (csShaderVariable*));
00117 }
00118 else
00119 {
00120 if (ownArray)
00121 cs_free (varArray);
00122 ownArray = false;
00123 varArray = other.varArray;
00124 }
00125 return *this;
00126 }
00127
00129 void Setup (size_t size)
00130 {
00131 if (ownArray)
00132 cs_free (varArray);
00133
00134 csShaderVariableStack::size = size;
00135 varArray = 0;
00136
00137 if (size > 0)
00138 {
00139 varArray = (csShaderVariable**)cs_malloc (size * sizeof(csShaderVariable*));
00140 ownArray = true;
00141
00142 memset (varArray, 0, size * sizeof(csShaderVariable*));
00143 }
00144 }
00145
00147 void Setup (csShaderVariable** stack, size_t size)
00148 {
00149 if (ownArray)
00150 cs_free (varArray);
00151
00152 varArray = stack;
00153 csShaderVariableStack::size = size;
00154 ownArray = false;
00155 }
00156
00158 void Setup (const csShaderVariableStack& stack)
00159 {
00160 if (ownArray)
00161 cs_free (varArray);
00162
00163 varArray = stack.varArray;
00164 size = stack.size;
00165 ownArray = false;
00166 }
00167
00169 void MakeOwnArray ()
00170 {
00171 if (ownArray) return;
00172 csShaderVariable** newArray =
00173 (csShaderVariable**)cs_malloc (size * sizeof(csShaderVariable*));
00174 memcpy (newArray, varArray, size * sizeof(csShaderVariable*));
00175 varArray = newArray;
00176 ownArray = true;
00177 }
00178
00180 inline size_t GetSize () const
00181 {
00182 return size;
00183 }
00184
00186 csShaderVariable*& operator[] (size_t index)
00187 {
00188 CS_ASSERT(index < size);
00189 return varArray[index];
00190 }
00191
00192 csShaderVariable* const& operator[] (size_t index) const
00193 {
00194 CS_ASSERT(index < size);
00195 return varArray[index];
00196 }
00197
00199 void Clear ()
00200 {
00201 if(varArray && size > 0)
00202 memset (varArray, 0, sizeof(csShaderVariable*)*size);
00203 }
00204
00206 void MergeFront (const csShaderVariableStack& other)
00207 {
00208 CS_ASSERT(other.size >= size);
00209 for (size_t i = 0; i < size; ++i)
00210 {
00211 if (!varArray[i])
00212 varArray[i] = other.varArray[i];
00213 }
00214 }
00215
00217 void MergeBack (const csShaderVariableStack& other)
00218 {
00219 CS_ASSERT(other.size >= size);
00220 for (size_t i = 0; i < size; ++i)
00221 {
00222 if (other.varArray[i])
00223 varArray[i] = other.varArray[i];
00224 }
00225 }
00226
00234 bool Copy (const csShaderVariableStack& other)
00235 {
00236 CS_ASSERT(other.size == size);
00237 if (varArray == other.varArray) return false;
00238 memcpy (varArray, other.varArray, sizeof(csShaderVariable*)*size);
00239 return true;
00240 }
00241 private:
00242 csShaderVariable** varArray;
00243 size_t size;
00244 bool ownArray;
00245 };
00247
00249
00252 static inline csShaderVariable* csGetShaderVariableFromStack (
00253 const csShaderVariableStack& stack,
00254 const CS::ShaderVarStringID &name)
00255 {
00256 if ((name != CS::InvalidShaderVarStringID)
00257 && (size_t (name) < stack.GetSize ()))
00258 {
00259 return stack[name];
00260 }
00261 return 0;
00262 }
00264
00269 struct iShaderVariableContext : public virtual iBase
00270 {
00271 SCF_INTERFACE(iShaderVariableContext, 2, 2, 1);
00272
00278 virtual void AddVariable (csShaderVariable *variable) = 0;
00279
00281 virtual csShaderVariable* GetVariable (CS::ShaderVarStringID name) const = 0;
00282
00284 csShaderVariable* GetVariableAdd (CS::ShaderVarStringID name)
00285 {
00286 csShaderVariable* sv;
00287 sv = GetVariable (name);
00288 if (sv == 0)
00289 {
00290 csRef<csShaderVariable> nsv (
00291 csPtr<csShaderVariable> (new csShaderVariable (name)));
00292 AddVariable (nsv);
00293 sv = nsv;
00294 }
00295 return sv;
00296 }
00297
00299 virtual const csRefArray<csShaderVariable>& GetShaderVariables () const = 0;
00300
00305 virtual void PushVariables (csShaderVariableStack& stack) const = 0;
00306
00308 virtual bool IsEmpty () const = 0;
00309
00316 virtual void ReplaceVariable (csShaderVariable* variable) = 0;
00317
00319 virtual void Clear() = 0;
00320
00322 virtual bool RemoveVariable (csShaderVariable* variable) = 0;
00323
00325 virtual bool RemoveVariable (CS::ShaderVarStringID name) = 0;
00326 };
00327
00331 enum csShaderTagPresence
00332 {
00337 TagNeutral,
00341 TagForbidden,
00347 TagRequired
00348 };
00349
00353 struct iShaderManager : public virtual iShaderVariableContext
00354 {
00355 SCF_INTERFACE (iShaderManager, 4, 0, 0);
00360 virtual void RegisterShader (iShader* shader) = 0;
00362 virtual void UnregisterShader (iShader* shader) = 0;
00364 virtual void UnregisterShaders () = 0;
00366 virtual iShader* GetShader (const char* name) = 0;
00368 virtual const csRefArray<iShader> &GetShaders () = 0;
00369
00371 virtual void RegisterCompiler (iShaderCompiler* compiler) = 0;
00373 virtual iShaderCompiler* GetCompiler(const char* name) = 0;
00374
00378 virtual void RegisterShaderVariableAccessor (const char* name,
00379 iShaderVariableAccessor* accessor) = 0;
00383 virtual void UnregisterShaderVariableAccessor (const char* name,
00384 iShaderVariableAccessor* accessor) = 0;
00388 virtual iShaderVariableAccessor* GetShaderVariableAccessor (
00389 const char* name) = 0;
00390
00394 virtual void UnregisterShaderVariableAcessors () = 0;
00395
00397 virtual csShaderVariableStack& GetShaderVariableStack () = 0;
00398
00407 virtual void SetTagOptions (csStringID tag, csShaderTagPresence presence,
00408 int priority = 0) = 0;
00413 virtual void GetTagOptions (csStringID tag, csShaderTagPresence& presence,
00414 int& priority) = 0;
00415
00419 virtual const csSet<csStringID>& GetTags (csShaderTagPresence presence,
00420 int& count) = 0;
00421
00425 virtual iShaderVarStringSet* GetSVNameStringset () const = 0;
00426
00428 virtual iHierarchicalCache* GetShaderCache() = 0;
00429
00430 enum
00431 {
00432 cachePriorityLowest = 0,
00433 cachePriorityGlobal = 100,
00434 cachePriorityApp = 200,
00435 cachePriorityUser = 300,
00436 cachePriorityHighest = 400
00437 };
00438 virtual void AddSubShaderCache (iHierarchicalCache* cache,
00439 int priority = cachePriorityApp) = 0;
00441 virtual iHierarchicalCache* AddSubCacheDirectory (const char* cacheDir,
00442 int priority = cachePriorityApp, bool readOnly = false) = 0;
00443 virtual void RemoveSubShaderCache (iHierarchicalCache* cache) = 0;
00444 virtual void RemoveAllSubShaderCaches () = 0;
00445 };
00446
00454 struct csShaderMetadata
00455 {
00457 const char *description;
00458
00464 uint numberOfLights;
00465
00467 csShaderMetadata ()
00468 : description (0), numberOfLights (0)
00469 {}
00470 };
00471
00475 struct iShaderPriorityList : public virtual iBase
00476 {
00477 SCF_INTERFACE (iShaderPriorityList, 1,0,0);
00479 virtual size_t GetCount () const = 0;
00481 virtual int GetPriority (size_t idx) const = 0;
00482 };
00483
00488 struct iShader : public virtual iShaderVariableContext
00489 {
00490 SCF_INTERFACE(iShader, 5, 0, 0);
00491
00493 virtual iObject* QueryObject () = 0;
00494
00496 virtual const char* GetFileName () = 0;
00497
00499 virtual void SetFileName (const char* filename) = 0;
00500
00511 virtual size_t GetTicket (const CS::Graphics::RenderMeshModes& modes,
00512 const csShaderVariableStack& stack) = 0;
00513
00515 virtual size_t GetNumberOfPasses (size_t ticket) = 0;
00516
00518 virtual bool ActivatePass (size_t ticket, size_t number) = 0;
00519
00521 virtual bool SetupPass (size_t ticket, const CS::Graphics::RenderMesh *mesh,
00522 CS::Graphics::RenderMeshModes& modes,
00523 const csShaderVariableStack& stack) = 0;
00524
00529 virtual bool TeardownPass (size_t ticket) = 0;
00530
00532 virtual bool DeactivatePass (size_t ticket) = 0;
00533
00535 enum SVUserFlags
00536 {
00538 svuTextures = (1 << 0),
00540 svuBuffers = (1 << 1),
00542 svuVProc = (1 << 2),
00544 svuVP = (1 << 3),
00546 svuFP = (1 << 4),
00547
00549 svuAll = 0xffff
00550 };
00551
00566 virtual void GetUsedShaderVars (size_t ticket, csBitArray& bits,
00567 uint userFlags = svuAll) const = 0;
00568
00570 virtual const csShaderMetadata& GetMetadata () const = 0;
00571
00576 virtual void PushShaderVariables (csShaderVariableStack& stack,
00577 size_t ticket) const = 0;
00578
00587 virtual size_t GetPrioritiesTicket (const CS::Graphics::RenderMeshModes& modes,
00588 const csShaderVariableStack& stack) = 0;
00593 virtual csPtr<iShaderPriorityList> GetAvailablePriorities (size_t prioTicket) const = 0;
00598 virtual csPtr<iString> GetTechniqueMetadata (int priority, const char* dataKey) const = 0;
00603 virtual csPtr<iShader> ForceTechnique (int priority) = 0;
00605 };
00606
00607
00613 struct iShaderCompiler : public virtual iBase
00614 {
00615 SCF_INTERFACE (iShaderCompiler, 1,0,0);
00617 virtual const char* GetName() = 0;
00618
00627 virtual csPtr<iShader> CompileShader (
00628 iLoaderContext* ldr_context, iDocumentNode *templ,
00629 int forcepriority = -1) = 0;
00630
00632 virtual bool ValidateTemplate (iDocumentNode *templ) = 0;
00633
00635 virtual bool IsTemplateToCompiler (iDocumentNode *templ) = 0;
00636
00642 virtual csPtr<iShaderPriorityList> GetPriorities (
00643 iDocumentNode* templ) = 0;
00644
00661 virtual bool PrecacheShader (iDocumentNode* node,
00662 iHierarchicalCache* cacheTo, bool quick = false) = 0;
00663 };
00664
00665 #endif // __CS_IVIDEO_SHADER_H__