1 /*
2 -----------------------------------------------------------------------------
3 This source file is part of OGRE
4 (Object-oriented Graphics Rendering Engine)
5 For the latest info, see http://www.ogre3d.org/
6 
7 Copyright (c) 2000-2014 Torus Knot Software Ltd
8 
9 Permission is hereby granted, free of charge, to any person obtaining a copy
10 of this software and associated documentation files (the "Software"), to deal
11 in the Software without restriction, including without limitation the rights
12 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 copies of the Software, and to permit persons to whom the Software is
14 furnished to do so, subject to the following conditions:
15 
16 The above copyright notice and this permission notice shall be included in
17 all copies or substantial portions of the Software.
18 
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 THE SOFTWARE.
26 -----------------------------------------------------------------------------
27 */
28 #ifndef __CgProgram_H__
29 #define __CgProgram_H__
30 
31 #include "OgreCgPrerequisites.h"
32 #include "OgreHighLevelGpuProgram.h"
33 #include "OgreStringVector.h"
34 
35 namespace Ogre {
36     /** \addtogroup Plugins
37     *  @{
38     */
39     /** \addtogroup CgProgramManager
40     *  @{
41     */
42     /** Specialisation of HighLevelGpuProgram to provide support for nVidia's CG language.
43     @remarks
44         Cg can be used to compile common, high-level, C-like code down to assembler
45         language for both GL and Direct3D, for multiple graphics cards. You must
46         supply a list of profiles which your program must support using
47         setProfiles() before the program is loaded in order for this to work. The
48         program will then negotiate with the renderer to compile the appropriate program
49         for the API and graphics card capabilities.
50     */
51     class CgProgram : public HighLevelGpuProgram
52     {
53     public:
54         /// Command object for setting entry point
55         class CmdEntryPoint : public ParamCommand
56         {
57         public:
58             String doGet(const void* target) const;
59             void doSet(void* target, const String& val);
60         };
61         /// Command object for setting profiles
62         class CmdProfiles : public ParamCommand
63         {
64         public:
65             String doGet(const void* target) const;
66             void doSet(void* target, const String& val);
67         };
68         /// Command object for setting compilation arguments
69         class CmdArgs : public ParamCommand
70         {
71         public:
72             String doGet(const void* target) const;
73             void doSet(void* target, const String& val);
74         };
75 
76     protected:
77 
78         static CmdEntryPoint msCmdEntryPoint;
79         static CmdProfiles msCmdProfiles;
80         static CmdArgs msCmdArgs;
81 
82         /// The CG context to use, passed in by factory
83         CGcontext mCgContext;
84         /** Internal load implementation, must be implemented by subclasses.
85         */
86         void loadFromSource(void);
87         /** Internal method for creating an appropriate low-level program from this
88         high-level program, must be implemented by subclasses. */
89         void createLowLevelImpl(void);
90         /// Internal unload implementation, must be implemented by subclasses
91         void unloadHighLevelImpl(void);
92         /// Populate the passed parameters with name->index map, must be overridden
93         void buildConstantDefinitions() const;
94 
95         /// Load the high-level part in a thread-safe way, required for delegate functionality
96         void loadHighLevelSafe();
97 
98         /// Recurse down structures getting data on parameters
99         void recurseParams(CGparameter param, size_t contextArraySize = 1);
100         /// Turn a Cg type into a GpuConstantType and number of elements
101         void mapTypeAndElementSize(CGtype cgType, bool isRegisterCombiner, GpuConstantDefinition& def) const;
102 
103         StringVector mProfiles;
104         String mEntryPoint;
105         String mSelectedProfile;
106         String mProgramString;
107         CGprofile mSelectedCgProfile;
108         // Unfortunately Cg uses char** for arguments - bleh
109         // This is a null-terminated list of char* (each null terminated)
110         char** mCgArguments;
111 
112         GpuConstantDefinitionMap mParametersMap;
113         size_t mParametersMapSizeAsBuffer;
114         std::map<String,int> mSamplerRegisterMap;
115         CGenum mInputOp, mOutputOp;
116 
117         /// Internal method which works out which profile to use for this program
118         void selectProfile(void);
119         /// Internal method which merges manual and automatic compile arguments
120         void buildArgs(void);
121         /// Releases memory for the horrible Cg char**
122         void freeCgArgs(void);
123 
124         void getMicrocodeFromCache(uint32 id);
125         void compileMicrocode(void);
126         void addMicrocodeToCache(uint32 id);
127 
128     private:
129         HighLevelGpuProgramPtr mDelegate;
130         String getHighLevelLanguage() const;
131         String getHighLevelTarget() const;
132         void fixHighLevelOutput(String& hlSource);
133 
134 
135     public:
136         CgProgram(ResourceManager* creator, const String& name, ResourceHandle handle,
137             const String& group, bool isManual, ManualResourceLoader* loader,
138             CGcontext context);
139         ~CgProgram();
140 
141         /** Sets the entry point for this program ie the first method called. */
setEntryPoint(const String & entryPoint)142         void setEntryPoint(const String& entryPoint) { mEntryPoint = entryPoint; }
143         /** Gets the entry point defined for this program. */
getEntryPoint(void)144         const String& getEntryPoint(void) const { return mEntryPoint; }
145         /** Sets the Cg profiles which can be supported by the program. */
146         void setProfiles(const StringVector& profiles);
147         /** Gets the Cg profiles which can be supported by the program. */
getProfiles(void)148         const StringVector& getProfiles(void) const { return mProfiles; }
149         /// Overridden from GpuProgram
150         bool isSupported(void) const;
151         /// Overridden from GpuProgram
152         const String& getLanguage(void) const;
153 
154         GpuProgramParametersSharedPtr createParameters();
155         GpuProgram* _getBindingDelegate();
156 
157         bool isSkeletalAnimationIncluded(void) const;
158         bool isMorphAnimationIncluded(void) const;
159         bool isPoseAnimationIncluded(void) const;
160         bool isVertexTextureFetchRequired(void) const;
161         GpuProgramParametersSharedPtr getDefaultParameters(void);
162         bool hasDefaultParameters(void) const;
163         bool getPassSurfaceAndLightStates(void) const;
164         bool getPassFogStates(void) const;
165         bool getPassTransformStates(void) const;
166         bool hasCompileError(void) const;
167         void resetCompileError(void);
168         size_t getSize(void) const;
169         void touch(void);
170     };
171     /** @} */
172     /** @} */
173 }
174 
175 #endif
176