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-2013 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 #include "OgreStableHeaders.h"
29 #include "OgreGpuProgramParams.h"
30 #include "OgreHighLevelGpuProgram.h"
31 #include "OgreGpuProgramManager.h"
32 #include "OgreVector3.h"
33 #include "OgreVector4.h"
34 #include "OgreDualQuaternion.h"
35 #include "OgreAutoParamDataSource.h"
36 #include "OgreLight.h"
37 #include "OgreRoot.h"
38 #include "OgreRenderSystem.h"
39 #include "OgreRenderSystemCapabilities.h"
40 #include "OgreStringConverter.h"
41 #include "OgreLogManager.h"
42 
43 
44 namespace Ogre
45 {
46 
47 	//---------------------------------------------------------------------
48 	GpuProgramParameters::AutoConstantDefinition GpuProgramParameters::AutoConstantDictionary[] = {
49 		AutoConstantDefinition(ACT_WORLD_MATRIX,                  "world_matrix",                16, ET_REAL, ACDT_NONE),
50 		AutoConstantDefinition(ACT_INVERSE_WORLD_MATRIX,          "inverse_world_matrix",        16, ET_REAL, ACDT_NONE),
51 		AutoConstantDefinition(ACT_TRANSPOSE_WORLD_MATRIX,             "transpose_world_matrix",            16, ET_REAL, ACDT_NONE),
52 		AutoConstantDefinition(ACT_INVERSE_TRANSPOSE_WORLD_MATRIX, "inverse_transpose_world_matrix", 16, ET_REAL, ACDT_NONE),
53 
54 		AutoConstantDefinition(ACT_WORLD_MATRIX_ARRAY_3x4,        "world_matrix_array_3x4",      12, ET_REAL, ACDT_NONE),
55 		AutoConstantDefinition(ACT_WORLD_MATRIX_ARRAY,            "world_matrix_array",          16, ET_REAL, ACDT_NONE),
56 		AutoConstantDefinition(ACT_WORLD_DUALQUATERNION_ARRAY_2x4, "world_dualquaternion_array_2x4",      8, ET_REAL, ACDT_NONE),
57 		AutoConstantDefinition(ACT_WORLD_SCALE_SHEAR_MATRIX_ARRAY_3x4, "world_scale_shear_matrix_array_3x4", 9, ET_REAL, ACDT_NONE),
58 		AutoConstantDefinition(ACT_VIEW_MATRIX,                   "view_matrix",                 16, ET_REAL, ACDT_NONE),
59 		AutoConstantDefinition(ACT_INVERSE_VIEW_MATRIX,           "inverse_view_matrix",         16, ET_REAL, ACDT_NONE),
60 		AutoConstantDefinition(ACT_TRANSPOSE_VIEW_MATRIX,              "transpose_view_matrix",             16, ET_REAL, ACDT_NONE),
61 		AutoConstantDefinition(ACT_INVERSE_TRANSPOSE_VIEW_MATRIX,       "inverse_transpose_view_matrix",     16, ET_REAL, ACDT_NONE),
62 
63 		AutoConstantDefinition(ACT_PROJECTION_MATRIX,             "projection_matrix",           16, ET_REAL, ACDT_NONE),
64 		AutoConstantDefinition(ACT_INVERSE_PROJECTION_MATRIX,          "inverse_projection_matrix",         16, ET_REAL, ACDT_NONE),
65 		AutoConstantDefinition(ACT_TRANSPOSE_PROJECTION_MATRIX,        "transpose_projection_matrix",       16, ET_REAL, ACDT_NONE),
66 		AutoConstantDefinition(ACT_INVERSE_TRANSPOSE_PROJECTION_MATRIX, "inverse_transpose_projection_matrix", 16, ET_REAL, ACDT_NONE),
67 
68 		AutoConstantDefinition(ACT_VIEWPROJ_MATRIX,               "viewproj_matrix",             16, ET_REAL, ACDT_NONE),
69 		AutoConstantDefinition(ACT_INVERSE_VIEWPROJ_MATRIX,       "inverse_viewproj_matrix",     16, ET_REAL, ACDT_NONE),
70 		AutoConstantDefinition(ACT_TRANSPOSE_VIEWPROJ_MATRIX,          "transpose_viewproj_matrix",         16, ET_REAL, ACDT_NONE),
71 		AutoConstantDefinition(ACT_INVERSE_TRANSPOSE_VIEWPROJ_MATRIX,   "inverse_transpose_viewproj_matrix", 16, ET_REAL, ACDT_NONE),
72 
73 		AutoConstantDefinition(ACT_WORLDVIEW_MATRIX,              "worldview_matrix",            16, ET_REAL, ACDT_NONE),
74 		AutoConstantDefinition(ACT_INVERSE_WORLDVIEW_MATRIX,      "inverse_worldview_matrix",    16, ET_REAL, ACDT_NONE),
75 		AutoConstantDefinition(ACT_TRANSPOSE_WORLDVIEW_MATRIX,         "transpose_worldview_matrix",        16, ET_REAL, ACDT_NONE),
76 		AutoConstantDefinition(ACT_INVERSE_TRANSPOSE_WORLDVIEW_MATRIX, "inverse_transpose_worldview_matrix", 16, ET_REAL, ACDT_NONE),
77 
78 		AutoConstantDefinition(ACT_WORLDVIEWPROJ_MATRIX,          "worldviewproj_matrix",        16, ET_REAL, ACDT_NONE),
79 		AutoConstantDefinition(ACT_INVERSE_WORLDVIEWPROJ_MATRIX,       "inverse_worldviewproj_matrix",      16, ET_REAL, ACDT_NONE),
80 		AutoConstantDefinition(ACT_TRANSPOSE_WORLDVIEWPROJ_MATRIX,     "transpose_worldviewproj_matrix",    16, ET_REAL, ACDT_NONE),
81 		AutoConstantDefinition(ACT_INVERSE_TRANSPOSE_WORLDVIEWPROJ_MATRIX, "inverse_transpose_worldviewproj_matrix", 16, ET_REAL, ACDT_NONE),
82 
83 		AutoConstantDefinition(ACT_RENDER_TARGET_FLIPPING,          "render_target_flipping",         1, ET_REAL, ACDT_NONE),
84 		AutoConstantDefinition(ACT_VERTEX_WINDING,          "vertex_winding",         1, ET_REAL, ACDT_NONE),
85 
86 		AutoConstantDefinition(ACT_FOG_COLOUR,                    "fog_colour",                   4, ET_REAL, ACDT_NONE),
87 		AutoConstantDefinition(ACT_FOG_PARAMS,                    "fog_params",                   4, ET_REAL, ACDT_NONE),
88 
89 		AutoConstantDefinition(ACT_SURFACE_AMBIENT_COLOUR,          "surface_ambient_colour",           4, ET_REAL, ACDT_NONE),
90 		AutoConstantDefinition(ACT_SURFACE_DIFFUSE_COLOUR,          "surface_diffuse_colour",           4, ET_REAL, ACDT_NONE),
91 		AutoConstantDefinition(ACT_SURFACE_SPECULAR_COLOUR,         "surface_specular_colour",          4, ET_REAL, ACDT_NONE),
92 		AutoConstantDefinition(ACT_SURFACE_EMISSIVE_COLOUR,         "surface_emissive_colour",          4, ET_REAL, ACDT_NONE),
93 		AutoConstantDefinition(ACT_SURFACE_SHININESS,               "surface_shininess",                1, ET_REAL, ACDT_NONE),
94 		AutoConstantDefinition(ACT_SURFACE_ALPHA_REJECTION_VALUE,   "surface_alpha_rejection_value",    1, ET_REAL, ACDT_NONE),
95 
96 		AutoConstantDefinition(ACT_LIGHT_COUNT,                   "light_count",                  1, ET_REAL, ACDT_NONE),
97 
98 		AutoConstantDefinition(ACT_AMBIENT_LIGHT_COLOUR,          "ambient_light_colour",         4, ET_REAL, ACDT_NONE),
99 		AutoConstantDefinition(ACT_LIGHT_DIFFUSE_COLOUR,          "light_diffuse_colour",         4, ET_REAL, ACDT_INT),
100 		AutoConstantDefinition(ACT_LIGHT_SPECULAR_COLOUR,         "light_specular_colour",        4, ET_REAL, ACDT_INT),
101 		AutoConstantDefinition(ACT_LIGHT_ATTENUATION,             "light_attenuation",            4, ET_REAL, ACDT_INT),
102 		AutoConstantDefinition(ACT_SPOTLIGHT_PARAMS,              "spotlight_params",             4, ET_REAL, ACDT_INT),
103 		AutoConstantDefinition(ACT_LIGHT_POSITION,                "light_position",               4, ET_REAL, ACDT_INT),
104 		AutoConstantDefinition(ACT_LIGHT_POSITION_OBJECT_SPACE,   "light_position_object_space",  4, ET_REAL, ACDT_INT),
105 		AutoConstantDefinition(ACT_LIGHT_POSITION_VIEW_SPACE,          "light_position_view_space",    4, ET_REAL, ACDT_INT),
106 		AutoConstantDefinition(ACT_LIGHT_DIRECTION,               "light_direction",              4, ET_REAL, ACDT_INT),
107 		AutoConstantDefinition(ACT_LIGHT_DIRECTION_OBJECT_SPACE,  "light_direction_object_space", 4, ET_REAL, ACDT_INT),
108 		AutoConstantDefinition(ACT_LIGHT_DIRECTION_VIEW_SPACE,         "light_direction_view_space",   4, ET_REAL, ACDT_INT),
109 		AutoConstantDefinition(ACT_LIGHT_DISTANCE_OBJECT_SPACE,   "light_distance_object_space",  1, ET_REAL, ACDT_INT),
110 		AutoConstantDefinition(ACT_LIGHT_POWER_SCALE,   		  "light_power",  1, ET_REAL, ACDT_INT),
111 		AutoConstantDefinition(ACT_LIGHT_DIFFUSE_COLOUR_POWER_SCALED, "light_diffuse_colour_power_scaled",         4, ET_REAL, ACDT_INT),
112 		AutoConstantDefinition(ACT_LIGHT_SPECULAR_COLOUR_POWER_SCALED, "light_specular_colour_power_scaled",        4, ET_REAL, ACDT_INT),
113 		AutoConstantDefinition(ACT_LIGHT_DIFFUSE_COLOUR_ARRAY,          "light_diffuse_colour_array",         4, ET_REAL, ACDT_INT),
114 		AutoConstantDefinition(ACT_LIGHT_SPECULAR_COLOUR_ARRAY,         "light_specular_colour_array",        4, ET_REAL, ACDT_INT),
115 		AutoConstantDefinition(ACT_LIGHT_DIFFUSE_COLOUR_POWER_SCALED_ARRAY, "light_diffuse_colour_power_scaled_array",         4, ET_REAL, ACDT_INT),
116 		AutoConstantDefinition(ACT_LIGHT_SPECULAR_COLOUR_POWER_SCALED_ARRAY, "light_specular_colour_power_scaled_array",        4, ET_REAL, ACDT_INT),
117 		AutoConstantDefinition(ACT_LIGHT_ATTENUATION_ARRAY,             "light_attenuation_array",            4, ET_REAL, ACDT_INT),
118 		AutoConstantDefinition(ACT_LIGHT_POSITION_ARRAY,                "light_position_array",               4, ET_REAL, ACDT_INT),
119 		AutoConstantDefinition(ACT_LIGHT_POSITION_OBJECT_SPACE_ARRAY,   "light_position_object_space_array",  4, ET_REAL, ACDT_INT),
120 		AutoConstantDefinition(ACT_LIGHT_POSITION_VIEW_SPACE_ARRAY,          "light_position_view_space_array",    4, ET_REAL, ACDT_INT),
121 		AutoConstantDefinition(ACT_LIGHT_DIRECTION_ARRAY,               "light_direction_array",              4, ET_REAL, ACDT_INT),
122 		AutoConstantDefinition(ACT_LIGHT_DIRECTION_OBJECT_SPACE_ARRAY,  "light_direction_object_space_array", 4, ET_REAL, ACDT_INT),
123 		AutoConstantDefinition(ACT_LIGHT_DIRECTION_VIEW_SPACE_ARRAY,         "light_direction_view_space_array",   4, ET_REAL, ACDT_INT),
124 		AutoConstantDefinition(ACT_LIGHT_DISTANCE_OBJECT_SPACE_ARRAY,   "light_distance_object_space_array",  1, ET_REAL, ACDT_INT),
125 		AutoConstantDefinition(ACT_LIGHT_POWER_SCALE_ARRAY,   		  "light_power_array",  1, ET_REAL, ACDT_INT),
126 		AutoConstantDefinition(ACT_SPOTLIGHT_PARAMS_ARRAY,              "spotlight_params_array",             4, ET_REAL, ACDT_INT),
127 
128 		AutoConstantDefinition(ACT_DERIVED_AMBIENT_LIGHT_COLOUR,    "derived_ambient_light_colour",     4, ET_REAL, ACDT_NONE),
129 		AutoConstantDefinition(ACT_DERIVED_SCENE_COLOUR,            "derived_scene_colour",             4, ET_REAL, ACDT_NONE),
130 		AutoConstantDefinition(ACT_DERIVED_LIGHT_DIFFUSE_COLOUR,    "derived_light_diffuse_colour",     4, ET_REAL, ACDT_INT),
131 		AutoConstantDefinition(ACT_DERIVED_LIGHT_SPECULAR_COLOUR,   "derived_light_specular_colour",    4, ET_REAL, ACDT_INT),
132 		AutoConstantDefinition(ACT_DERIVED_LIGHT_DIFFUSE_COLOUR_ARRAY,  "derived_light_diffuse_colour_array",   4, ET_REAL, ACDT_INT),
133 		AutoConstantDefinition(ACT_DERIVED_LIGHT_SPECULAR_COLOUR_ARRAY, "derived_light_specular_colour_array",  4, ET_REAL, ACDT_INT),
134 
135 		AutoConstantDefinition(ACT_LIGHT_NUMBER,   					  "light_number",  1, ET_REAL, ACDT_INT),
136 		AutoConstantDefinition(ACT_LIGHT_CASTS_SHADOWS, 			  "light_casts_shadows",  1, ET_REAL, ACDT_INT),
137 		AutoConstantDefinition(ACT_LIGHT_CASTS_SHADOWS_ARRAY,     "light_casts_shadows_array",  1, ET_REAL, ACDT_INT),
138 
139 		AutoConstantDefinition(ACT_SHADOW_EXTRUSION_DISTANCE,     "shadow_extrusion_distance",    1, ET_REAL, ACDT_INT),
140 		AutoConstantDefinition(ACT_CAMERA_POSITION,               "camera_position",              3, ET_REAL, ACDT_NONE),
141 		AutoConstantDefinition(ACT_CAMERA_POSITION_OBJECT_SPACE,  "camera_position_object_space", 3, ET_REAL, ACDT_NONE),
142 		AutoConstantDefinition(ACT_TEXTURE_VIEWPROJ_MATRIX,       "texture_viewproj_matrix",     16, ET_REAL, ACDT_INT),
143 		AutoConstantDefinition(ACT_TEXTURE_VIEWPROJ_MATRIX_ARRAY, "texture_viewproj_matrix_array", 16, ET_REAL, ACDT_INT),
144 		AutoConstantDefinition(ACT_TEXTURE_WORLDVIEWPROJ_MATRIX,  "texture_worldviewproj_matrix",16, ET_REAL, ACDT_INT),
145 		AutoConstantDefinition(ACT_TEXTURE_WORLDVIEWPROJ_MATRIX_ARRAY, "texture_worldviewproj_matrix_array",16, ET_REAL, ACDT_INT),
146 		AutoConstantDefinition(ACT_SPOTLIGHT_VIEWPROJ_MATRIX,       "spotlight_viewproj_matrix",     16, ET_REAL, ACDT_INT),
147 		AutoConstantDefinition(ACT_SPOTLIGHT_VIEWPROJ_MATRIX_ARRAY, "spotlight_viewproj_matrix_array", 16, ET_REAL, ACDT_INT),
148 		AutoConstantDefinition(ACT_SPOTLIGHT_WORLDVIEWPROJ_MATRIX,  "spotlight_worldviewproj_matrix",16, ET_REAL, ACDT_INT),
149 		AutoConstantDefinition(ACT_SPOTLIGHT_WORLDVIEWPROJ_MATRIX_ARRAY,  "spotlight_worldviewproj_matrix_array",16, ET_REAL, ACDT_INT),
150 		AutoConstantDefinition(ACT_CUSTOM,                        "custom",                       4, ET_REAL, ACDT_INT),  // *** needs to be tested
151 		AutoConstantDefinition(ACT_TIME,                               "time",                               1, ET_REAL, ACDT_REAL),
152 		AutoConstantDefinition(ACT_TIME_0_X,                      "time_0_x",                     4, ET_REAL, ACDT_REAL),
153 		AutoConstantDefinition(ACT_COSTIME_0_X,                   "costime_0_x",                  4, ET_REAL, ACDT_REAL),
154 		AutoConstantDefinition(ACT_SINTIME_0_X,                   "sintime_0_x",                  4, ET_REAL, ACDT_REAL),
155 		AutoConstantDefinition(ACT_TANTIME_0_X,                   "tantime_0_x",                  4, ET_REAL, ACDT_REAL),
156 		AutoConstantDefinition(ACT_TIME_0_X_PACKED,               "time_0_x_packed",              4, ET_REAL, ACDT_REAL),
157 		AutoConstantDefinition(ACT_TIME_0_1,                      "time_0_1",                     4, ET_REAL, ACDT_REAL),
158 		AutoConstantDefinition(ACT_COSTIME_0_1,                   "costime_0_1",                  4, ET_REAL, ACDT_REAL),
159 		AutoConstantDefinition(ACT_SINTIME_0_1,                   "sintime_0_1",                  4, ET_REAL, ACDT_REAL),
160 		AutoConstantDefinition(ACT_TANTIME_0_1,                   "tantime_0_1",                  4, ET_REAL, ACDT_REAL),
161 		AutoConstantDefinition(ACT_TIME_0_1_PACKED,               "time_0_1_packed",              4, ET_REAL, ACDT_REAL),
162 		AutoConstantDefinition(ACT_TIME_0_2PI,                    "time_0_2pi",                   4, ET_REAL, ACDT_REAL),
163 		AutoConstantDefinition(ACT_COSTIME_0_2PI,                 "costime_0_2pi",                4, ET_REAL, ACDT_REAL),
164 		AutoConstantDefinition(ACT_SINTIME_0_2PI,                 "sintime_0_2pi",                4, ET_REAL, ACDT_REAL),
165 		AutoConstantDefinition(ACT_TANTIME_0_2PI,                 "tantime_0_2pi",                4, ET_REAL, ACDT_REAL),
166 		AutoConstantDefinition(ACT_TIME_0_2PI_PACKED,             "time_0_2pi_packed",            4, ET_REAL, ACDT_REAL),
167 		AutoConstantDefinition(ACT_FRAME_TIME,                    "frame_time",                   1, ET_REAL, ACDT_REAL),
168 		AutoConstantDefinition(ACT_FPS,                           "fps",                          1, ET_REAL, ACDT_NONE),
169 		AutoConstantDefinition(ACT_VIEWPORT_WIDTH,                "viewport_width",               1, ET_REAL, ACDT_NONE),
170 		AutoConstantDefinition(ACT_VIEWPORT_HEIGHT,               "viewport_height",              1, ET_REAL, ACDT_NONE),
171 		AutoConstantDefinition(ACT_INVERSE_VIEWPORT_WIDTH,        "inverse_viewport_width",       1, ET_REAL, ACDT_NONE),
172 		AutoConstantDefinition(ACT_INVERSE_VIEWPORT_HEIGHT,       "inverse_viewport_height",      1, ET_REAL, ACDT_NONE),
173 		AutoConstantDefinition(ACT_VIEWPORT_SIZE,                 "viewport_size",                4, ET_REAL, ACDT_NONE),
174 		AutoConstantDefinition(ACT_VIEW_DIRECTION,                "view_direction",               3, ET_REAL, ACDT_NONE),
175 		AutoConstantDefinition(ACT_VIEW_SIDE_VECTOR,              "view_side_vector",             3, ET_REAL, ACDT_NONE),
176 		AutoConstantDefinition(ACT_VIEW_UP_VECTOR,                "view_up_vector",               3, ET_REAL, ACDT_NONE),
177 		AutoConstantDefinition(ACT_FOV,                           "fov",                          1, ET_REAL, ACDT_NONE),
178 		AutoConstantDefinition(ACT_NEAR_CLIP_DISTANCE,            "near_clip_distance",           1, ET_REAL, ACDT_NONE),
179 		AutoConstantDefinition(ACT_FAR_CLIP_DISTANCE,             "far_clip_distance",            1, ET_REAL, ACDT_NONE),
180 		AutoConstantDefinition(ACT_PASS_NUMBER,                        "pass_number",                        1, ET_REAL, ACDT_NONE),
181 		AutoConstantDefinition(ACT_PASS_ITERATION_NUMBER,              "pass_iteration_number",              1, ET_REAL, ACDT_NONE),
182 		AutoConstantDefinition(ACT_ANIMATION_PARAMETRIC,               "animation_parametric",               4, ET_REAL, ACDT_INT),
183 		AutoConstantDefinition(ACT_TEXEL_OFFSETS,               "texel_offsets",				  4, ET_REAL, ACDT_NONE),
184 		AutoConstantDefinition(ACT_SCENE_DEPTH_RANGE,           "scene_depth_range",			  4, ET_REAL, ACDT_NONE),
185 		AutoConstantDefinition(ACT_SHADOW_SCENE_DEPTH_RANGE,    "shadow_scene_depth_range",		  4, ET_REAL, ACDT_INT),
186 		AutoConstantDefinition(ACT_SHADOW_SCENE_DEPTH_RANGE_ARRAY,    "shadow_scene_depth_range_array",		  4, ET_REAL, ACDT_INT),
187 		AutoConstantDefinition(ACT_SHADOW_COLOUR,				"shadow_colour",				  4, ET_REAL, ACDT_NONE),
188 		AutoConstantDefinition(ACT_TEXTURE_SIZE,                "texture_size",                   4, ET_REAL, ACDT_INT),
189 		AutoConstantDefinition(ACT_INVERSE_TEXTURE_SIZE,        "inverse_texture_size",           4, ET_REAL, ACDT_INT),
190 		AutoConstantDefinition(ACT_PACKED_TEXTURE_SIZE,         "packed_texture_size",            4, ET_REAL, ACDT_INT),
191 		AutoConstantDefinition(ACT_TEXTURE_MATRIX,  "texture_matrix", 16, ET_REAL, ACDT_INT),
192 		AutoConstantDefinition(ACT_LOD_CAMERA_POSITION,               "lod_camera_position",              3, ET_REAL, ACDT_NONE),
193 		AutoConstantDefinition(ACT_LOD_CAMERA_POSITION_OBJECT_SPACE,  "lod_camera_position_object_space", 3, ET_REAL, ACDT_NONE),
194 		AutoConstantDefinition(ACT_LIGHT_CUSTOM,	"light_custom", 4, ET_REAL, ACDT_INT)
195 	};
196 
197 	bool GpuNamedConstants::msGenerateAllConstantDefinitionArrayEntries = false;
198 
199 	//---------------------------------------------------------------------
generateConstantDefinitionArrayEntries(const String & paramName,const GpuConstantDefinition & baseDef)200 	void GpuNamedConstants::generateConstantDefinitionArrayEntries(
201 		const String& paramName, const GpuConstantDefinition& baseDef)
202 	{
203 		// Copy definition for use with arrays
204 		GpuConstantDefinition arrayDef = baseDef;
205 		arrayDef.arraySize = 1;
206 		String arrayName;
207 
208 		// Add parameters for array accessors
209 		// [0] will refer to the same location, [1+] will increment
210 		// only populate others individually up to 16 array slots so as not to get out of hand,
211 		// unless the system has been explicitly configured to allow all the parameters to be added
212 
213 		// paramName[0] version will always exist
214 		size_t maxArrayIndex = 1;
215 		if (baseDef.arraySize <= 16 || msGenerateAllConstantDefinitionArrayEntries)
216 			maxArrayIndex = baseDef.arraySize;
217 
218 		for (size_t i = 0; i < maxArrayIndex; i++)
219 		{
220 			arrayName = paramName + "[" + StringConverter::toString(i) + "]";
221 			map.insert(GpuConstantDefinitionMap::value_type(arrayName, arrayDef));
222 			// increment location
223 			arrayDef.physicalIndex += arrayDef.elementSize;
224 		}
225 		// note no increment of buffer sizes since this is shared with main array def
226 
227 	}
228 
229 	//---------------------------------------------------------------------
getGenerateAllConstantDefinitionArrayEntries()230 	bool GpuNamedConstants::getGenerateAllConstantDefinitionArrayEntries()
231 	{
232 		return msGenerateAllConstantDefinitionArrayEntries;
233 	}
234 
235 	//---------------------------------------------------------------------
setGenerateAllConstantDefinitionArrayEntries(bool generateAll)236 	void GpuNamedConstants::setGenerateAllConstantDefinitionArrayEntries(bool generateAll)
237 	{
238 		msGenerateAllConstantDefinitionArrayEntries = generateAll;
239 	}
240 	//---------------------------------------------------------------------
241 	//  GpuNamedConstants methods
242 	//---------------------------------------------------------------------
save(const String & filename) const243 	void GpuNamedConstants::save(const String& filename) const
244 	{
245 		GpuNamedConstantsSerializer ser;
246 		ser.exportNamedConstants(this, filename);
247 	}
248 	//---------------------------------------------------------------------
load(DataStreamPtr & stream)249 	void GpuNamedConstants::load(DataStreamPtr& stream)
250 	{
251 		GpuNamedConstantsSerializer ser;
252 		ser.importNamedConstants(stream, this);
253 	}
254     //-----------------------------------------------------------------------------
calculateSize(void) const255     size_t GpuNamedConstants::calculateSize(void) const
256     {
257         size_t memSize = 0;
258 
259         // Buffer size refs
260         memSize += 3 * sizeof(size_t);
261 
262         // Tally up constant defs
263         memSize += sizeof(GpuConstantDefinition) * map.size();
264 
265         return memSize;
266     }
267 	//---------------------------------------------------------------------
268 	//  GpuNamedConstantsSerializer methods
269 	//---------------------------------------------------------------------
GpuNamedConstantsSerializer()270 	GpuNamedConstantsSerializer::GpuNamedConstantsSerializer()
271 	{
272 		mVersion = "[v1.0]";
273 	}
274 	//---------------------------------------------------------------------
~GpuNamedConstantsSerializer()275 	GpuNamedConstantsSerializer::~GpuNamedConstantsSerializer()
276 	{
277 
278 	}
279 	//---------------------------------------------------------------------
exportNamedConstants(const GpuNamedConstants * pConsts,const String & filename,Endian endianMode)280 	void GpuNamedConstantsSerializer::exportNamedConstants(
281 		const GpuNamedConstants* pConsts, const String& filename, Endian endianMode)
282 	{
283 		std::fstream *f = OGRE_NEW_T(std::fstream, MEMCATEGORY_GENERAL)();
284 		f->open(filename.c_str(), std::ios::binary | std::ios::out);
285 		DataStreamPtr stream(OGRE_NEW FileStreamDataStream(f));
286 
287 		exportNamedConstants(pConsts, stream, endianMode);
288 
289 		stream->close();
290 	}
291 	//---------------------------------------------------------------------
exportNamedConstants(const GpuNamedConstants * pConsts,DataStreamPtr stream,Endian endianMode)292 	void GpuNamedConstantsSerializer::exportNamedConstants(
293 		const GpuNamedConstants* pConsts, DataStreamPtr stream, Endian endianMode)
294 	{
295 		// Decide on endian mode
296 		determineEndianness(endianMode);
297 
298 		String msg;
299 		mStream =stream;
300 		if (!stream->isWriteable())
301 		{
302 			OGRE_EXCEPT(Exception::ERR_CANNOT_WRITE_TO_FILE,
303 				"Unable to write to stream " + stream->getName(),
304 				"GpuNamedConstantsSerializer::exportSkeleton");
305 		}
306 
307 		writeFileHeader();
308 
309 		writeInts(((const uint32*)&pConsts->floatBufferSize), 1);
310 		writeInts(((const uint32*)&pConsts->intBufferSize), 1);
311 
312 		// simple export of all the named constants, no chunks
313 		// name, physical index
314 		for (GpuConstantDefinitionMap::const_iterator i = pConsts->map.begin();
315 			i != pConsts->map.end(); ++i)
316 		{
317 			const String& name = i->first;
318 			const GpuConstantDefinition& def = i->second;
319 
320 			writeString(name);
321 			writeInts(((const uint32*)&def.physicalIndex), 1);
322 			writeInts(((const uint32*)&def.logicalIndex), 1);
323 			uint32 constType = static_cast<uint32>(def.constType);
324 			writeInts(&constType, 1);
325 			writeInts(((const uint32*)&def.elementSize), 1);
326 			writeInts(((const uint32*)&def.arraySize), 1);
327 		}
328 
329 	}
330 	//---------------------------------------------------------------------
importNamedConstants(DataStreamPtr & stream,GpuNamedConstants * pDest)331 	void GpuNamedConstantsSerializer::importNamedConstants(
332 		DataStreamPtr& stream, GpuNamedConstants* pDest)
333 	{
334 		// Determine endianness (must be the first thing we do!)
335 		determineEndianness(stream);
336 
337 		// Check header
338 		readFileHeader(stream);
339 
340 		// simple file structure, no chunks
341 		pDest->map.clear();
342 
343 		readInts(stream, ((uint32*)&pDest->floatBufferSize), 1);
344 		readInts(stream, ((uint32*)&pDest->intBufferSize), 1);
345 
346 		while (!stream->eof())
347 		{
348 			GpuConstantDefinition def;
349 			String name = readString(stream);
350 			// Hmm, deal with trailing information
351 			if (name.empty())
352 				continue;
353 			readInts(stream, ((uint32*)&def.physicalIndex), 1);
354 			readInts(stream, ((uint32*)&def.logicalIndex), 1);
355 			uint constType;
356 			readInts(stream, &constType, 1);
357 			def.constType = static_cast<GpuConstantType>(constType);
358 			readInts(stream, ((uint32*)&def.elementSize), 1);
359 			readInts(stream, ((uint32*)&def.arraySize), 1);
360 
361 			pDest->map[name] = def;
362 
363 		}
364 
365 
366 
367 	}
368 
369 	//-----------------------------------------------------------------------------
370 	//      GpuSharedParameters Methods
371 	//-----------------------------------------------------------------------------
GpuSharedParameters(const String & name)372 	GpuSharedParameters::GpuSharedParameters(const String& name)
373 		:mName(name)
374 		, mFrameLastUpdated(Root::getSingleton().getNextFrameNumber())
375 		, mVersion(0)
376 	{
377 
378 	}
379 	//---------------------------------------------------------------------
~GpuSharedParameters()380 	GpuSharedParameters::~GpuSharedParameters()
381 	{
382 
383 	}
384     //-----------------------------------------------------------------------------
calculateSize(void) const385     size_t GpuSharedParameters::calculateSize(void) const
386     {
387         size_t memSize = 0;
388 
389         memSize += sizeof(float) * mFloatConstants.size();
390         memSize += sizeof(double) * mDoubleConstants.size();
391         memSize += sizeof(int) * mIntConstants.size();
392         memSize += mName.size() * sizeof(char);
393         memSize += sizeof(Any);
394         memSize += sizeof(size_t);
395         memSize += sizeof(unsigned long);
396 
397         return memSize;
398     }
399 	//---------------------------------------------------------------------
addConstantDefinition(const String & name,GpuConstantType constType,size_t arraySize)400 	void GpuSharedParameters::addConstantDefinition(const String& name, GpuConstantType constType, size_t arraySize)
401 	{
402 		if (mNamedConstants.map.find(name) != mNamedConstants.map.end())
403 		{
404 			OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
405 				"Constant entry with name '" + name + "' already exists. ",
406 				"GpuSharedParameters::addConstantDefinition");
407 		}
408 		GpuConstantDefinition def;
409 		def.arraySize = arraySize;
410 		def.constType = constType;
411 		// for compatibility we do not pad values to multiples of 4
412 		// when it comes to arrays, user is responsible for creating matching defs
413 		def.elementSize = GpuConstantDefinition::getElementSize(constType, false);
414 
415 		// not used
416 		def.logicalIndex = 0;
417 		def.variability = (uint16)GPV_GLOBAL;
418 
419 		if (def.isFloat())
420 		{
421 			def.physicalIndex = mFloatConstants.size();
422 			mFloatConstants.resize(mFloatConstants.size() + def.arraySize * def.elementSize);
423 		}
424 		else
425 		{
426 			def.physicalIndex = mIntConstants.size();
427 			mIntConstants.resize(mIntConstants.size() + def.arraySize * def.elementSize);
428 		}
429 
430 		mNamedConstants.map[name] = def;
431 
432 		++mVersion;
433 	}
434 	//---------------------------------------------------------------------
removeConstantDefinition(const String & name)435 	void GpuSharedParameters::removeConstantDefinition(const String& name)
436 	{
437 		GpuConstantDefinitionMap::iterator i = mNamedConstants.map.find(name);
438 		if (i != mNamedConstants.map.end())
439 		{
440 			GpuConstantDefinition& def = i->second;
441 			bool isFloat = def.isFloat();
442 			size_t numElems = def.elementSize * def.arraySize;
443 
444 			for (GpuConstantDefinitionMap::iterator j = mNamedConstants.map.begin();
445 				j != mNamedConstants.map.end(); ++j)
446 			{
447 				GpuConstantDefinition& otherDef = j->second;
448 				bool otherIsFloat = otherDef.isFloat();
449 
450 				// same type, and comes after in the buffer
451 				if ( ((isFloat && otherIsFloat) || (!isFloat && !otherIsFloat)) &&
452 					otherDef.physicalIndex > def.physicalIndex)
453 				{
454 					// adjust index
455 					otherDef.physicalIndex -= numElems;
456 				}
457 			}
458 
459 			// remove floats and reduce buffer
460 			if (isFloat)
461 			{
462 				mNamedConstants.floatBufferSize -= numElems;
463 
464 				FloatConstantList::iterator beg = mFloatConstants.begin();
465 				std::advance(beg, def.physicalIndex);
466 				FloatConstantList::iterator en = beg;
467 				std::advance(en, numElems);
468 				mFloatConstants.erase(beg, en);
469 			}
470 			else
471 			{
472 				mNamedConstants.intBufferSize -= numElems;
473 
474 				IntConstantList::iterator beg = mIntConstants.begin();
475 				std::advance(beg, def.physicalIndex);
476 				IntConstantList::iterator en = beg;
477 				std::advance(en, numElems);
478 				mIntConstants.erase(beg, en);
479 
480 			}
481 
482 			++mVersion;
483 
484 		}
485 
486 	}
487 	//---------------------------------------------------------------------
removeAllConstantDefinitions()488 	void GpuSharedParameters::removeAllConstantDefinitions()
489 	{
490 		mNamedConstants.map.clear();
491 		mNamedConstants.floatBufferSize = 0;
492 		mNamedConstants.intBufferSize = 0;
493 		mFloatConstants.clear();
494 		mIntConstants.clear();
495 	}
496 	//---------------------------------------------------------------------
getConstantDefinitionIterator(void) const497 	GpuConstantDefinitionIterator GpuSharedParameters::getConstantDefinitionIterator(void) const
498 	{
499 		return GpuConstantDefinitionIterator(mNamedConstants.map.begin(), mNamedConstants.map.end());
500 	}
501 	//---------------------------------------------------------------------
getConstantDefinition(const String & name) const502 	const GpuConstantDefinition& GpuSharedParameters::getConstantDefinition(const String& name) const
503 	{
504 		GpuConstantDefinitionMap::const_iterator i = mNamedConstants.map.find(name);
505 		if (i == mNamedConstants.map.end())
506 		{
507 			OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
508 				"Constant entry with name '" + name + "' does not exist. ",
509 				"GpuSharedParameters::getConstantDefinition");
510 		}
511 		return i->second;
512 	}
513 	//---------------------------------------------------------------------
getConstantDefinitions() const514 	const GpuNamedConstants& GpuSharedParameters::getConstantDefinitions() const
515 	{
516 		return mNamedConstants;
517 	}
518 	//---------------------------------------------------------------------
setNamedConstant(const String & name,Real val)519 	void GpuSharedParameters::setNamedConstant(const String& name, Real val)
520 	{
521 		setNamedConstant(name, &val, 1);
522 	}
523 	//---------------------------------------------------------------------
setNamedConstant(const String & name,int val)524 	void GpuSharedParameters::setNamedConstant(const String& name, int val)
525 	{
526 		setNamedConstant(name, &val, 1);
527 	}
528 	//---------------------------------------------------------------------
setNamedConstant(const String & name,const Vector4 & vec)529 	void GpuSharedParameters::setNamedConstant(const String& name, const Vector4& vec)
530 	{
531 		setNamedConstant(name, vec.ptr(), 4);
532 	}
533 	//---------------------------------------------------------------------
setNamedConstant(const String & name,const Vector3 & vec)534 	void GpuSharedParameters::setNamedConstant(const String& name, const Vector3& vec)
535 	{
536 		setNamedConstant(name, vec.ptr(), 3);
537 	}
538 	//---------------------------------------------------------------------
setNamedConstant(const String & name,const Vector2 & vec)539 	void GpuSharedParameters::setNamedConstant(const String& name, const Vector2& vec)
540 	{
541 		setNamedConstant(name, vec.ptr(), 2);
542 	}
543 	//---------------------------------------------------------------------
setNamedConstant(const String & name,const Matrix4 & m)544 	void GpuSharedParameters::setNamedConstant(const String& name, const Matrix4& m)
545 	{
546 		setNamedConstant(name, m[0], 16);
547 	}
548 	//---------------------------------------------------------------------
setNamedConstant(const String & name,const Matrix4 * m,size_t numEntries)549 	void GpuSharedParameters::setNamedConstant(const String& name, const Matrix4* m, size_t numEntries)
550 	{
551 		setNamedConstant(name, m[0][0], 16 * numEntries);
552 	}
553 	//---------------------------------------------------------------------
setNamedConstant(const String & name,const float * val,size_t count)554 	void GpuSharedParameters::setNamedConstant(const String& name, const float *val, size_t count)
555 	{
556 		GpuConstantDefinitionMap::const_iterator i = mNamedConstants.map.find(name);
557 		if (i != mNamedConstants.map.end())
558 		{
559 			const GpuConstantDefinition& def = i->second;
560 			memcpy(&mFloatConstants[def.physicalIndex], val,
561 				sizeof(float) * std::min(count, def.elementSize * def.arraySize));
562 		}
563 
564 		_markDirty();
565 
566 	}
567 	//---------------------------------------------------------------------
setNamedConstant(const String & name,const double * val,size_t count)568 	void GpuSharedParameters::setNamedConstant(const String& name, const double *val, size_t count)
569 	{
570 		GpuConstantDefinitionMap::const_iterator i = mNamedConstants.map.find(name);
571 		if (i != mNamedConstants.map.end())
572 		{
573 			const GpuConstantDefinition& def = i->second;
574 
575 			count = std::min(count, def.elementSize * def.arraySize);
576 			const double* src = val;
577 			float* dst = &mFloatConstants[def.physicalIndex];
578 			for (size_t v = 0; v < count; ++v)
579 			{
580 				*dst++ = static_cast<float>(*src++);
581 			}
582 		}
583 
584 		_markDirty();
585 
586 	}
587 	//---------------------------------------------------------------------
setNamedConstant(const String & name,const ColourValue & colour)588 	void GpuSharedParameters::setNamedConstant(const String& name, const ColourValue& colour)
589 	{
590 		setNamedConstant(name, colour.ptr(), 4);
591 	}
592 	//---------------------------------------------------------------------
setNamedConstant(const String & name,const int * val,size_t count)593 	void GpuSharedParameters::setNamedConstant(const String& name, const int *val, size_t count)
594 	{
595 		GpuConstantDefinitionMap::const_iterator i = mNamedConstants.map.find(name);
596 		if (i != mNamedConstants.map.end())
597 		{
598 			const GpuConstantDefinition& def = i->second;
599 			memcpy(&mIntConstants[def.physicalIndex], val,
600 				sizeof(int) * std::min(count, def.elementSize * def.arraySize));
601 		}
602 
603 		_markDirty();
604 
605 	}
606 	//---------------------------------------------------------------------
_markDirty()607 	void GpuSharedParameters::_markDirty()
608 	{
609 		mFrameLastUpdated = Root::getSingleton().getNextFrameNumber();
610 	}
611 
612 	//-----------------------------------------------------------------------------
613 	//      GpuSharedParametersUsage Methods
614 	//-----------------------------------------------------------------------------
GpuSharedParametersUsage(GpuSharedParametersPtr sharedParams,GpuProgramParameters * params)615 	GpuSharedParametersUsage::GpuSharedParametersUsage(GpuSharedParametersPtr sharedParams,
616 		GpuProgramParameters* params)
617 		: mSharedParams(sharedParams)
618 		, mParams(params)
619 	{
620 		initCopyData();
621 	}
622 	//---------------------------------------------------------------------
initCopyData()623 	void GpuSharedParametersUsage::initCopyData()
624 	{
625 
626 		mCopyDataList.clear();
627 
628 		const GpuConstantDefinitionMap& sharedmap = mSharedParams->getConstantDefinitions().map;
629 		for (GpuConstantDefinitionMap::const_iterator i = sharedmap.begin(); i != sharedmap.end(); ++i)
630 		{
631 			const String& pName = i->first;
632 			const GpuConstantDefinition& shareddef = i->second;
633 
634 			const GpuConstantDefinition* instdef = mParams->_findNamedConstantDefinition(pName, false);
635 			if (instdef)
636 			{
637 				// Check that the definitions are the same
638 				if (instdef->constType == shareddef.constType &&
639 					instdef->arraySize <= shareddef.arraySize)
640 				{
641 					CopyDataEntry e;
642 					e.srcDefinition = &shareddef;
643 					e.dstDefinition = instdef;
644 					mCopyDataList.push_back(e);
645 				}
646 			}
647 
648 		}
649 
650 		mCopyDataVersion = mSharedParams->getVersion();
651 
652 	}
653 	//---------------------------------------------------------------------
_copySharedParamsToTargetParams()654 	void GpuSharedParametersUsage::_copySharedParamsToTargetParams()
655 	{
656 		// check copy data version
657 		if (mCopyDataVersion != mSharedParams->getVersion())
658 			initCopyData();
659 
660 		for (CopyDataList::iterator i = mCopyDataList.begin(); i != mCopyDataList.end(); ++i)
661 		{
662 			CopyDataEntry& e = *i;
663 
664 			if (e.dstDefinition->isFloat())
665 			{
666 				const float* pSrc = mSharedParams->getFloatPointer(e.srcDefinition->physicalIndex);
667 				float* pDst = mParams->getFloatPointer(e.dstDefinition->physicalIndex);
668 
669 				// Deal with matrix transposition here!!!
670 				// transposition is specific to the dest param set, shared params don't do it
671 				if (mParams->getTransposeMatrices() && (e.dstDefinition->constType == GCT_MATRIX_4X4))
672 				{
673                     // for each matrix that needs to be transposed and copied,
674                     for (size_t iMat = 0; iMat < e.dstDefinition->arraySize; ++iMat)
675                     {
676                         for (int row = 0; row < 4; ++row)
677                             for (int col = 0; col < 4; ++col)
678                                 pDst[row * 4 + col] = pSrc[col * 4 + row];
679                         pSrc += 16;
680                         pDst += 16;
681                     }
682 				}
683 				else
684 				{
685 					if (e.dstDefinition->elementSize == e.srcDefinition->elementSize)
686 					{
687 						// simple copy
688 						memcpy(pDst, pSrc, sizeof(float) * e.dstDefinition->elementSize * e.dstDefinition->arraySize);
689 					}
690 					else
691 					{
692 						// target params may be padded to 4 elements, shared params are packed
693 						assert(e.dstDefinition->elementSize % 4 == 0);
694 						size_t iterations = e.dstDefinition->elementSize / 4
695 							* e.dstDefinition->arraySize;
696                         assert(iterations > 0);
697 						size_t valsPerIteration = e.srcDefinition->elementSize;
698 						for (size_t l = 0; l < iterations; ++l)
699 						{
700 							memcpy(pDst, pSrc, sizeof(float) * valsPerIteration);
701 							pSrc += valsPerIteration;
702 							pDst += 4;
703 						}
704 					}
705 				}
706 			}
707 			else if (e.dstDefinition->isDouble())
708 			{
709 				const double* pSrc = mSharedParams->getDoublePointer(e.srcDefinition->physicalIndex);
710 				double* pDst = mParams->getDoublePointer(e.dstDefinition->physicalIndex);
711 
712 				// Deal with matrix transposition here!!!
713 				// transposition is specific to the dest param set, shared params don't do it
714 				if (mParams->getTransposeMatrices() && (e.dstDefinition->constType == GCT_MATRIX_DOUBLE_4X4))
715 				{
716                     // for each matrix that needs to be transposed and copied,
717                     for (size_t iMat = 0; iMat < e.dstDefinition->arraySize; ++iMat)
718                     {
719                         for (int row = 0; row < 4; ++row)
720                             for (int col = 0; col < 4; ++col)
721                                 pDst[row * 4 + col] = pSrc[col * 4 + row];
722                         pSrc += 16;
723                         pDst += 16;
724                     }
725 				}
726 				else
727 				{
728 					if (e.dstDefinition->elementSize == e.srcDefinition->elementSize)
729 					{
730 						// simple copy
731 						memcpy(pDst, pSrc, sizeof(double) * e.dstDefinition->elementSize * e.dstDefinition->arraySize);
732 					}
733 					else
734 					{
735 						// target params may be padded to 4 elements, shared params are packed
736 						assert(e.dstDefinition->elementSize % 4 == 0);
737 						size_t iterations = e.dstDefinition->elementSize / 4
738                         * e.dstDefinition->arraySize;
739                         assert(iterations > 0);
740 						size_t valsPerIteration = e.srcDefinition->elementSize;
741 						for (size_t l = 0; l < iterations; ++l)
742 						{
743 							memcpy(pDst, pSrc, sizeof(double) * valsPerIteration);
744 							pSrc += valsPerIteration;
745 							pDst += 4;
746 						}
747 					}
748 				}
749 			}
750 			else
751 			{
752 				const int* pSrc = mSharedParams->getIntPointer(e.srcDefinition->physicalIndex);
753 				int* pDst = mParams->getIntPointer(e.dstDefinition->physicalIndex);
754 
755 				if (e.dstDefinition->elementSize == e.srcDefinition->elementSize)
756 				{
757 					// simple copy
758 					memcpy(pDst, pSrc, sizeof(int) * e.dstDefinition->elementSize * e.dstDefinition->arraySize);
759 				}
760 				else
761 				{
762 					// target params may be padded to 4 elements, shared params are packed
763 					assert(e.dstDefinition->elementSize % 4 == 0);
764 					size_t iterations = (e.dstDefinition->elementSize / 4)
765 						* e.dstDefinition->arraySize;
766 					assert(iterations > 0);
767 					size_t valsPerIteration = e.srcDefinition->elementSize;
768 					for (size_t l = 0; l < iterations; ++l)
769 					{
770 						memcpy(pDst, pSrc, sizeof(int) * valsPerIteration);
771 						pSrc += valsPerIteration;
772 						pDst += 4;
773 					}
774 				}
775 			}
776 		}
777 	}
778 
779 
780 
781 	//-----------------------------------------------------------------------------
782 	//      GpuProgramParameters Methods
783 	//-----------------------------------------------------------------------------
GpuProgramParameters()784 	GpuProgramParameters::GpuProgramParameters() :
785 		mCombinedVariability(GPV_GLOBAL)
786 		, mTransposeMatrices(false)
787 		, mIgnoreMissingParams(false)
788 		, mActivePassIterationIndex(std::numeric_limits<size_t>::max())
789 	{
790 	}
791 	//-----------------------------------------------------------------------------
792 
GpuProgramParameters(const GpuProgramParameters & oth)793 	GpuProgramParameters::GpuProgramParameters(const GpuProgramParameters& oth)
794 	{
795 		*this = oth;
796 	}
797 
798 	//-----------------------------------------------------------------------------
operator =(const GpuProgramParameters & oth)799 	GpuProgramParameters& GpuProgramParameters::operator=(const GpuProgramParameters& oth)
800 	{
801 		// let compiler perform shallow copies of structures
802 		// AutoConstantEntry, RealConstantEntry, IntConstantEntry
803 		mFloatConstants = oth.mFloatConstants;
804 		mIntConstants  = oth.mIntConstants;
805 		mAutoConstants = oth.mAutoConstants;
806 		mFloatLogicalToPhysical = oth.mFloatLogicalToPhysical;
807 		mIntLogicalToPhysical = oth.mIntLogicalToPhysical;
808 		mNamedConstants = oth.mNamedConstants;
809 		copySharedParamSetUsage(oth.mSharedParamSets);
810 
811 		mCombinedVariability = oth.mCombinedVariability;
812 		mTransposeMatrices = oth.mTransposeMatrices;
813 		mIgnoreMissingParams  = oth.mIgnoreMissingParams;
814 		mActivePassIterationIndex = oth.mActivePassIterationIndex;
815 
816 		return *this;
817 	}
818 	//---------------------------------------------------------------------
copySharedParamSetUsage(const GpuSharedParamUsageList & srcList)819 	void GpuProgramParameters::copySharedParamSetUsage(const GpuSharedParamUsageList& srcList)
820 	{
821 		mSharedParamSets.clear();
822 		for (GpuSharedParamUsageList::const_iterator i = srcList.begin(); i != srcList.end(); ++i)
823 		{
824 			mSharedParamSets.push_back(GpuSharedParametersUsage(i->getSharedParams(), this));
825 		}
826 
827 	}
828     //-----------------------------------------------------------------------------
calculateSize(void) const829     size_t GpuProgramParameters::calculateSize(void) const
830     {
831         size_t memSize = 0;
832 
833         memSize += sizeof(float) * mFloatConstants.size();
834         memSize += sizeof(double) * mDoubleConstants.size();
835         memSize += sizeof(int) * mIntConstants.size();
836         memSize += sizeof(Any);
837         memSize += sizeof(size_t);
838         memSize += sizeof(bool) * 2;
839         memSize += sizeof(uint16);
840 
841         for (AutoConstantList::const_iterator i = mAutoConstants.begin();
842              i != mAutoConstants.end(); ++i)
843         {
844             memSize += sizeof((*i));
845         }
846 
847         if(!mFloatLogicalToPhysical.isNull())
848             memSize += mFloatLogicalToPhysical->bufferSize;
849         if(!mDoubleLogicalToPhysical.isNull())
850             memSize += mDoubleLogicalToPhysical->bufferSize;
851         if(!mIntLogicalToPhysical.isNull())
852             memSize += mIntLogicalToPhysical->bufferSize;
853 
854         return memSize;
855     }
856 	//---------------------------------------------------------------------
_setNamedConstants(const GpuNamedConstantsPtr & namedConstants)857 	void GpuProgramParameters::_setNamedConstants(
858 		const GpuNamedConstantsPtr& namedConstants)
859 	{
860 		mNamedConstants = namedConstants;
861 
862 		// Determine any extension to local buffers
863 
864 		// Size and reset buffer (fill with zero to make comparison later ok)
865 		if (namedConstants->floatBufferSize > mFloatConstants.size())
866 		{
867 			mFloatConstants.insert(mFloatConstants.end(),
868 				namedConstants->floatBufferSize - mFloatConstants.size(), 0.0f);
869 		}
870 		if (namedConstants->intBufferSize > mIntConstants.size())
871 		{
872 			mIntConstants.insert(mIntConstants.end(),
873 				namedConstants->intBufferSize - mIntConstants.size(), 0);
874 		}
875 	}
876 	//---------------------------------------------------------------------
_setLogicalIndexes(const GpuLogicalBufferStructPtr & floatIndexMap,const GpuLogicalBufferStructPtr & doubleIndexMap,const GpuLogicalBufferStructPtr & intIndexMap)877 	void GpuProgramParameters::_setLogicalIndexes(
878 		const GpuLogicalBufferStructPtr& floatIndexMap,
879         const GpuLogicalBufferStructPtr& doubleIndexMap,
880 		const GpuLogicalBufferStructPtr& intIndexMap)
881 	{
882 		mFloatLogicalToPhysical = floatIndexMap;
883 		mDoubleLogicalToPhysical = doubleIndexMap;
884 		mIntLogicalToPhysical = intIndexMap;
885 
886 		// resize the internal buffers
887 		// Note that these will only contain something after the first parameter
888 		// set has set some parameters
889 
890 		// Size and reset buffer (fill with zero to make comparison later ok)
891 		if (!floatIndexMap.isNull() && floatIndexMap->bufferSize > mFloatConstants.size())
892 		{
893 			mFloatConstants.insert(mFloatConstants.end(),
894 				floatIndexMap->bufferSize - mFloatConstants.size(), 0.0f);
895 		}
896 		if (!doubleIndexMap.isNull() && doubleIndexMap->bufferSize > mDoubleConstants.size())
897 		{
898 			mDoubleConstants.insert(mDoubleConstants.end(),
899                                    doubleIndexMap->bufferSize - mDoubleConstants.size(), 0.0f);
900 		}
901 		if (!intIndexMap.isNull() &&  intIndexMap->bufferSize > mIntConstants.size())
902 		{
903 			mIntConstants.insert(mIntConstants.end(),
904 				intIndexMap->bufferSize - mIntConstants.size(), 0);
905 		}
906 
907 	}
908 	//---------------------------------------------------------------------()
setConstant(size_t index,const Vector4 & vec)909 	void GpuProgramParameters::setConstant(size_t index, const Vector4& vec)
910 	{
911 		setConstant(index, vec.ptr(), 1);
912 	}
913 	//-----------------------------------------------------------------------------
setConstant(size_t index,Real val)914 	void GpuProgramParameters::setConstant(size_t index, Real val)
915 	{
916 		setConstant(index, Vector4(val, 0.0f, 0.0f, 0.0f));
917 	}
918 	//-----------------------------------------------------------------------------
setConstant(size_t index,const Vector3 & vec)919 	void GpuProgramParameters::setConstant(size_t index, const Vector3& vec)
920 	{
921 		setConstant(index, Vector4(vec.x, vec.y, vec.z, 1.0f));
922 	}
923 	//-----------------------------------------------------------------------------
setConstant(size_t index,const Vector2 & vec)924 	void GpuProgramParameters::setConstant(size_t index, const Vector2& vec)
925 	{
926 		setConstant(index, Vector4(vec.x, vec.y, 1.0f, 1.0f));
927 	}
928 	//-----------------------------------------------------------------------------
setConstant(size_t index,const Matrix4 & m)929 	void GpuProgramParameters::setConstant(size_t index, const Matrix4& m)
930 	{
931 		// set as 4x 4-element floats
932 		if (mTransposeMatrices)
933 		{
934 			Matrix4 t = m.transpose();
935 			GpuProgramParameters::setConstant(index, t[0], 4);
936 		}
937 		else
938 		{
939 			GpuProgramParameters::setConstant(index, m[0], 4);
940 		}
941 
942 	}
943 	//-----------------------------------------------------------------------------
setConstant(size_t index,const Matrix4 * pMatrix,size_t numEntries)944 	void GpuProgramParameters::setConstant(size_t index, const Matrix4* pMatrix,
945 		size_t numEntries)
946 	{
947 		if (mTransposeMatrices)
948 		{
949 			for (size_t i = 0; i < numEntries; ++i)
950 			{
951 				Matrix4 t = pMatrix[i].transpose();
952 				GpuProgramParameters::setConstant(index, t[0], 4);
953 				index += 4;
954 			}
955 		}
956 		else
957 		{
958 			GpuProgramParameters::setConstant(index, pMatrix[0][0], 4 * numEntries);
959 		}
960 
961 	}
962 	//-----------------------------------------------------------------------------
setConstant(size_t index,const ColourValue & colour)963 	void GpuProgramParameters::setConstant(size_t index, const ColourValue& colour)
964 	{
965 		setConstant(index, colour.ptr(), 1);
966 	}
967 	//-----------------------------------------------------------------------------
setConstant(size_t index,const float * val,size_t count)968 	void GpuProgramParameters::setConstant(size_t index, const float *val, size_t count)
969 	{
970 		// Raw buffer size is 4x count
971 		size_t rawCount = count * 4;
972 		// get physical index
973 		assert(!mFloatLogicalToPhysical.isNull() && "GpuProgram hasn't set up the logical -> physical map!");
974 
975 		size_t physicalIndex = _getFloatConstantPhysicalIndex(index, rawCount, GPV_GLOBAL);
976 
977 		// Copy
978 		_writeRawConstants(physicalIndex, val, rawCount);
979 
980 	}
981 	//-----------------------------------------------------------------------------
setConstant(size_t index,const double * val,size_t count)982 	void GpuProgramParameters::setConstant(size_t index, const double *val, size_t count)
983 	{
984 		// Raw buffer size is 4x count
985 		size_t rawCount = count * 4;
986 		// get physical index
987 		assert(!mFloatLogicalToPhysical.isNull() && "GpuProgram hasn't set up the logical -> physical map!");
988 
989 		size_t physicalIndex = _getFloatConstantPhysicalIndex(index, rawCount, GPV_GLOBAL);
990 		assert(physicalIndex + rawCount <= mFloatConstants.size());
991 		// Copy manually since cast required
992 		for (size_t i = 0; i < rawCount; ++i)
993 		{
994 			mFloatConstants[physicalIndex + i] =
995 				static_cast<float>(val[i]);
996 		}
997 
998 	}
999 	//-----------------------------------------------------------------------------
setConstant(size_t index,const int * val,size_t count)1000 	void GpuProgramParameters::setConstant(size_t index, const int *val, size_t count)
1001 	{
1002 		// Raw buffer size is 4x count
1003 		size_t rawCount = count * 4;
1004 		// get physical index
1005 		assert(!mIntLogicalToPhysical.isNull() && "GpuProgram hasn't set up the logical -> physical map!");
1006 
1007 		size_t physicalIndex = _getIntConstantPhysicalIndex(index, rawCount, GPV_GLOBAL);
1008 		// Copy
1009 		_writeRawConstants(physicalIndex, val, rawCount);
1010 	}
1011 	//-----------------------------------------------------------------------------
_writeRawConstant(size_t physicalIndex,const Vector4 & vec,size_t count)1012 	void GpuProgramParameters::_writeRawConstant(size_t physicalIndex, const Vector4& vec,
1013 		size_t count)
1014 	{
1015 		// remember, raw content access uses raw float count rather than float4
1016 		// write either the number requested (for packed types) or up to 4
1017 		_writeRawConstants(physicalIndex, vec.ptr(), std::min(count, (size_t)4));
1018 	}
1019 	//-----------------------------------------------------------------------------
_writeRawConstant(size_t physicalIndex,Real val)1020 	void GpuProgramParameters::_writeRawConstant(size_t physicalIndex, Real val)
1021 	{
1022 		_writeRawConstants(physicalIndex, &val, 1);
1023 	}
1024 	//-----------------------------------------------------------------------------
_writeRawConstant(size_t physicalIndex,Real val,size_t count)1025 	void GpuProgramParameters::_writeRawConstant(size_t physicalIndex, Real val, size_t count)
1026 	{
1027 		_writeRawConstants(physicalIndex, &val, count);
1028 	}
1029 	//-----------------------------------------------------------------------------
_writeRawConstant(size_t physicalIndex,int val)1030 	void GpuProgramParameters::_writeRawConstant(size_t physicalIndex, int val)
1031 	{
1032 		_writeRawConstants(physicalIndex, &val, 1);
1033 	}
1034 	//-----------------------------------------------------------------------------
_writeRawConstant(size_t physicalIndex,const Vector3 & vec)1035 	void GpuProgramParameters::_writeRawConstant(size_t physicalIndex, const Vector3& vec)
1036 	{
1037 		_writeRawConstants(physicalIndex, vec.ptr(), 3);
1038 	}
1039 	//-----------------------------------------------------------------------------
_writeRawConstant(size_t physicalIndex,const Vector2 & vec)1040 	void GpuProgramParameters::_writeRawConstant(size_t physicalIndex, const Vector2& vec)
1041 	{
1042 		_writeRawConstants(physicalIndex, vec.ptr(), 2);
1043 	}
1044 	//-----------------------------------------------------------------------------
_writeRawConstant(size_t physicalIndex,const Matrix4 & m,size_t elementCount)1045 	void GpuProgramParameters::_writeRawConstant(size_t physicalIndex, const Matrix4& m,size_t elementCount)
1046 	{
1047 
1048 		// remember, raw content access uses raw float count rather than float4
1049 		if (mTransposeMatrices)
1050 		{
1051 			Matrix4 t = m.transpose();
1052 			_writeRawConstants(physicalIndex, t[0], elementCount>16?16:elementCount);
1053 		}
1054 		else
1055 		{
1056 			_writeRawConstants(physicalIndex, m[0], elementCount>16?16:elementCount);
1057 		}
1058 
1059 	}
1060 	//-----------------------------------------------------------------------------
_writeRawConstant(size_t physicalIndex,const Matrix4 * pMatrix,size_t numEntries)1061 	void GpuProgramParameters::_writeRawConstant(size_t physicalIndex, const Matrix4* pMatrix, size_t numEntries)
1062 	{
1063 		// remember, raw content access uses raw float count rather than float4
1064 		if (mTransposeMatrices)
1065 		{
1066 			for (size_t i = 0; i < numEntries; ++i)
1067 			{
1068 				Matrix4 t = pMatrix[i].transpose();
1069 				_writeRawConstants(physicalIndex, t[0], 16);
1070 				physicalIndex += 16;
1071 			}
1072 		}
1073 		else
1074 		{
1075 			_writeRawConstants(physicalIndex, pMatrix[0][0], 16 * numEntries);
1076 		}
1077 
1078 
1079 	}
1080 	//-----------------------------------------------------------------------------
_writeRawConstant(size_t physicalIndex,const ColourValue & colour,size_t count)1081 	void GpuProgramParameters::_writeRawConstant(size_t physicalIndex,
1082 		const ColourValue& colour, size_t count)
1083 	{
1084 		// write either the number requested (for packed types) or up to 4
1085 		_writeRawConstants(physicalIndex, colour.ptr(), std::min(count, (size_t)4));
1086 	}
1087 	//-----------------------------------------------------------------------------
_writeRawConstants(size_t physicalIndex,const double * val,size_t count)1088 	void GpuProgramParameters::_writeRawConstants(size_t physicalIndex, const double* val, size_t count)
1089 	{
1090 		assert(physicalIndex + count <= mFloatConstants.size());
1091 		for (size_t i = 0; i < count; ++i)
1092 		{
1093 			mFloatConstants[physicalIndex+i] = static_cast<float>(val[i]);
1094 		}
1095 	}
1096 	//-----------------------------------------------------------------------------
_writeRawConstants(size_t physicalIndex,const float * val,size_t count)1097 	void GpuProgramParameters::_writeRawConstants(size_t physicalIndex, const float* val, size_t count)
1098 	{
1099 		assert(physicalIndex + count <= mFloatConstants.size());
1100 		memcpy(&mFloatConstants[physicalIndex], val, sizeof(float) * count);
1101 	}
1102 	//-----------------------------------------------------------------------------
_writeRawConstants(size_t physicalIndex,const int * val,size_t count)1103 	void GpuProgramParameters::_writeRawConstants(size_t physicalIndex, const int* val, size_t count)
1104 	{
1105 		assert(physicalIndex + count <= mIntConstants.size());
1106 		memcpy(&mIntConstants[physicalIndex], val, sizeof(int) * count);
1107 	}
1108 	//-----------------------------------------------------------------------------
_readRawConstants(size_t physicalIndex,size_t count,float * dest)1109 	void GpuProgramParameters::_readRawConstants(size_t physicalIndex, size_t count, float* dest)
1110 	{
1111 		assert(physicalIndex + count <= mFloatConstants.size());
1112 		memcpy(dest, &mFloatConstants[physicalIndex], sizeof(float) * count);
1113 	}
1114 	//-----------------------------------------------------------------------------
_readRawConstants(size_t physicalIndex,size_t count,int * dest)1115 	void GpuProgramParameters::_readRawConstants(size_t physicalIndex, size_t count, int* dest)
1116 	{
1117 		assert(physicalIndex + count <= mIntConstants.size());
1118 		memcpy(dest, &mIntConstants[physicalIndex], sizeof(int) * count);
1119 	}
1120 	//---------------------------------------------------------------------
deriveVariability(GpuProgramParameters::AutoConstantType act)1121 	uint16 GpuProgramParameters::deriveVariability(GpuProgramParameters::AutoConstantType act)
1122 	{
1123 		switch(act)
1124 		{
1125 		case ACT_VIEW_MATRIX:
1126 		case ACT_INVERSE_VIEW_MATRIX:
1127 		case ACT_TRANSPOSE_VIEW_MATRIX:
1128 		case ACT_INVERSE_TRANSPOSE_VIEW_MATRIX:
1129 		case ACT_PROJECTION_MATRIX:
1130 		case ACT_INVERSE_PROJECTION_MATRIX:
1131 		case ACT_TRANSPOSE_PROJECTION_MATRIX:
1132 		case ACT_INVERSE_TRANSPOSE_PROJECTION_MATRIX:
1133 		case ACT_VIEWPROJ_MATRIX:
1134 		case ACT_INVERSE_VIEWPROJ_MATRIX:
1135 		case ACT_TRANSPOSE_VIEWPROJ_MATRIX:
1136 		case ACT_INVERSE_TRANSPOSE_VIEWPROJ_MATRIX:
1137 		case ACT_RENDER_TARGET_FLIPPING:
1138 		case ACT_VERTEX_WINDING:
1139 		case ACT_AMBIENT_LIGHT_COLOUR:
1140 		case ACT_DERIVED_AMBIENT_LIGHT_COLOUR:
1141 		case ACT_DERIVED_SCENE_COLOUR:
1142 		case ACT_FOG_COLOUR:
1143 		case ACT_FOG_PARAMS:
1144 		case ACT_SURFACE_AMBIENT_COLOUR:
1145 		case ACT_SURFACE_DIFFUSE_COLOUR:
1146 		case ACT_SURFACE_SPECULAR_COLOUR:
1147 		case ACT_SURFACE_EMISSIVE_COLOUR:
1148 		case ACT_SURFACE_SHININESS:
1149 		case ACT_SURFACE_ALPHA_REJECTION_VALUE:
1150 		case ACT_CAMERA_POSITION:
1151 		case ACT_TIME:
1152 		case ACT_TIME_0_X:
1153 		case ACT_COSTIME_0_X:
1154 		case ACT_SINTIME_0_X:
1155 		case ACT_TANTIME_0_X:
1156 		case ACT_TIME_0_X_PACKED:
1157 		case ACT_TIME_0_1:
1158 		case ACT_COSTIME_0_1:
1159 		case ACT_SINTIME_0_1:
1160 		case ACT_TANTIME_0_1:
1161 		case ACT_TIME_0_1_PACKED:
1162 		case ACT_TIME_0_2PI:
1163 		case ACT_COSTIME_0_2PI:
1164 		case ACT_SINTIME_0_2PI:
1165 		case ACT_TANTIME_0_2PI:
1166 		case ACT_TIME_0_2PI_PACKED:
1167 		case ACT_FRAME_TIME:
1168 		case ACT_FPS:
1169 		case ACT_VIEWPORT_WIDTH:
1170 		case ACT_VIEWPORT_HEIGHT:
1171 		case ACT_INVERSE_VIEWPORT_WIDTH:
1172 		case ACT_INVERSE_VIEWPORT_HEIGHT:
1173 		case ACT_VIEWPORT_SIZE:
1174 		case ACT_TEXEL_OFFSETS:
1175 		case ACT_TEXTURE_SIZE:
1176 		case ACT_INVERSE_TEXTURE_SIZE:
1177 		case ACT_PACKED_TEXTURE_SIZE:
1178 		case ACT_SCENE_DEPTH_RANGE:
1179 		case ACT_VIEW_DIRECTION:
1180 		case ACT_VIEW_SIDE_VECTOR:
1181 		case ACT_VIEW_UP_VECTOR:
1182 		case ACT_FOV:
1183 		case ACT_NEAR_CLIP_DISTANCE:
1184 		case ACT_FAR_CLIP_DISTANCE:
1185 		case ACT_PASS_NUMBER:
1186 		case ACT_TEXTURE_MATRIX:
1187 		case ACT_LOD_CAMERA_POSITION:
1188 
1189 			return (uint16)GPV_GLOBAL;
1190 
1191 		case ACT_WORLD_MATRIX:
1192 		case ACT_INVERSE_WORLD_MATRIX:
1193 		case ACT_TRANSPOSE_WORLD_MATRIX:
1194 		case ACT_INVERSE_TRANSPOSE_WORLD_MATRIX:
1195 		case ACT_WORLD_MATRIX_ARRAY_3x4:
1196 		case ACT_WORLD_MATRIX_ARRAY:
1197 		case ACT_WORLD_DUALQUATERNION_ARRAY_2x4:
1198 		case ACT_WORLD_SCALE_SHEAR_MATRIX_ARRAY_3x4:
1199 		case ACT_WORLDVIEW_MATRIX:
1200 		case ACT_INVERSE_WORLDVIEW_MATRIX:
1201 		case ACT_TRANSPOSE_WORLDVIEW_MATRIX:
1202 		case ACT_INVERSE_TRANSPOSE_WORLDVIEW_MATRIX:
1203 		case ACT_WORLDVIEWPROJ_MATRIX:
1204 		case ACT_INVERSE_WORLDVIEWPROJ_MATRIX:
1205 		case ACT_TRANSPOSE_WORLDVIEWPROJ_MATRIX:
1206 		case ACT_INVERSE_TRANSPOSE_WORLDVIEWPROJ_MATRIX:
1207 		case ACT_CAMERA_POSITION_OBJECT_SPACE:
1208 		case ACT_LOD_CAMERA_POSITION_OBJECT_SPACE:
1209 		case ACT_CUSTOM:
1210 		case ACT_ANIMATION_PARAMETRIC:
1211 
1212 			return (uint16)GPV_PER_OBJECT;
1213 
1214 		case ACT_LIGHT_POSITION_OBJECT_SPACE:
1215 		case ACT_LIGHT_DIRECTION_OBJECT_SPACE:
1216 		case ACT_LIGHT_DISTANCE_OBJECT_SPACE:
1217 		case ACT_LIGHT_POSITION_OBJECT_SPACE_ARRAY:
1218 		case ACT_LIGHT_DIRECTION_OBJECT_SPACE_ARRAY:
1219 		case ACT_LIGHT_DISTANCE_OBJECT_SPACE_ARRAY:
1220 		case ACT_TEXTURE_WORLDVIEWPROJ_MATRIX:
1221 		case ACT_TEXTURE_WORLDVIEWPROJ_MATRIX_ARRAY:
1222 		case ACT_SPOTLIGHT_WORLDVIEWPROJ_MATRIX:
1223         case ACT_SPOTLIGHT_WORLDVIEWPROJ_MATRIX_ARRAY:
1224 		case ACT_SHADOW_EXTRUSION_DISTANCE:
1225 
1226 			// These depend on BOTH lights and objects
1227 			return ((uint16)GPV_PER_OBJECT) | ((uint16)GPV_LIGHTS);
1228 
1229 		case ACT_LIGHT_COUNT:
1230 		case ACT_LIGHT_DIFFUSE_COLOUR:
1231 		case ACT_LIGHT_SPECULAR_COLOUR:
1232 		case ACT_LIGHT_POSITION:
1233 		case ACT_LIGHT_DIRECTION:
1234 		case ACT_LIGHT_POSITION_VIEW_SPACE:
1235 		case ACT_LIGHT_DIRECTION_VIEW_SPACE:
1236 		case ACT_SHADOW_SCENE_DEPTH_RANGE:
1237         case ACT_SHADOW_SCENE_DEPTH_RANGE_ARRAY:
1238 		case ACT_SHADOW_COLOUR:
1239 		case ACT_LIGHT_POWER_SCALE:
1240 		case ACT_LIGHT_DIFFUSE_COLOUR_POWER_SCALED:
1241 		case ACT_LIGHT_SPECULAR_COLOUR_POWER_SCALED:
1242 		case ACT_LIGHT_NUMBER:
1243 		case ACT_LIGHT_CASTS_SHADOWS:
1244         case ACT_LIGHT_CASTS_SHADOWS_ARRAY:
1245 		case ACT_LIGHT_ATTENUATION:
1246 		case ACT_SPOTLIGHT_PARAMS:
1247 		case ACT_LIGHT_DIFFUSE_COLOUR_ARRAY:
1248 		case ACT_LIGHT_SPECULAR_COLOUR_ARRAY:
1249 		case ACT_LIGHT_DIFFUSE_COLOUR_POWER_SCALED_ARRAY:
1250 		case ACT_LIGHT_SPECULAR_COLOUR_POWER_SCALED_ARRAY:
1251 		case ACT_LIGHT_POSITION_ARRAY:
1252 		case ACT_LIGHT_DIRECTION_ARRAY:
1253 		case ACT_LIGHT_POSITION_VIEW_SPACE_ARRAY:
1254 		case ACT_LIGHT_DIRECTION_VIEW_SPACE_ARRAY:
1255 		case ACT_LIGHT_POWER_SCALE_ARRAY:
1256 		case ACT_LIGHT_ATTENUATION_ARRAY:
1257 		case ACT_SPOTLIGHT_PARAMS_ARRAY:
1258 		case ACT_TEXTURE_VIEWPROJ_MATRIX:
1259 		case ACT_TEXTURE_VIEWPROJ_MATRIX_ARRAY:
1260 		case ACT_SPOTLIGHT_VIEWPROJ_MATRIX:
1261 		case ACT_SPOTLIGHT_VIEWPROJ_MATRIX_ARRAY:
1262 		case ACT_LIGHT_CUSTOM:
1263 
1264 			return (uint16)GPV_LIGHTS;
1265 
1266 		case ACT_DERIVED_LIGHT_DIFFUSE_COLOUR:
1267 		case ACT_DERIVED_LIGHT_SPECULAR_COLOUR:
1268 		case ACT_DERIVED_LIGHT_DIFFUSE_COLOUR_ARRAY:
1269 		case ACT_DERIVED_LIGHT_SPECULAR_COLOUR_ARRAY:
1270 
1271 			return ((uint16)GPV_GLOBAL | (uint16)GPV_LIGHTS);
1272 
1273 		case ACT_PASS_ITERATION_NUMBER:
1274 
1275 			return (uint16)GPV_PASS_ITERATION_NUMBER;
1276 
1277 		default:
1278 			return (uint16)GPV_GLOBAL;
1279 		};
1280 
1281 	}
1282 	//---------------------------------------------------------------------
_getFloatConstantLogicalIndexUse(size_t logicalIndex,size_t requestedSize,uint16 variability)1283 	GpuLogicalIndexUse* GpuProgramParameters::_getFloatConstantLogicalIndexUse(
1284 		size_t logicalIndex, size_t requestedSize, uint16 variability)
1285 	{
1286 		if (mFloatLogicalToPhysical.isNull())
1287 			return 0;
1288 
1289 		GpuLogicalIndexUse* indexUse = 0;
1290 		OGRE_LOCK_MUTEX(mFloatLogicalToPhysical->mutex);
1291 
1292 			GpuLogicalIndexUseMap::iterator logi = mFloatLogicalToPhysical->map.find(logicalIndex);
1293 		if (logi == mFloatLogicalToPhysical->map.end())
1294 		{
1295 			if (requestedSize)
1296 			{
1297 				size_t physicalIndex = mFloatConstants.size();
1298 
1299 				// Expand at buffer end
1300 				mFloatConstants.insert(mFloatConstants.end(), requestedSize, 0.0f);
1301 
1302 				// Record extended size for future GPU params re-using this information
1303 				mFloatLogicalToPhysical->bufferSize = mFloatConstants.size();
1304 
1305 				// low-level programs will not know about mapping ahead of time, so
1306 				// populate it. Other params objects will be able to just use this
1307 				// accepted mapping since the constant structure will be the same
1308 
1309 				// Set up a mapping for all items in the count
1310 				size_t currPhys = physicalIndex;
1311 				size_t count = requestedSize / 4;
1312 				GpuLogicalIndexUseMap::iterator insertedIterator;
1313 
1314 				for (size_t logicalNum = 0; logicalNum < count; ++logicalNum)
1315 				{
1316 					GpuLogicalIndexUseMap::iterator it =
1317 						mFloatLogicalToPhysical->map.insert(
1318 						GpuLogicalIndexUseMap::value_type(
1319 						logicalIndex + logicalNum,
1320 						GpuLogicalIndexUse(currPhys, requestedSize, variability))).first;
1321 					currPhys += 4;
1322 
1323 					if (logicalNum == 0)
1324 						insertedIterator = it;
1325 				}
1326 
1327 				indexUse = &(insertedIterator->second);
1328 			}
1329 			else
1330 			{
1331 				// no match & ignore
1332 				return 0;
1333 			}
1334 
1335 		}
1336 		else
1337 		{
1338 			size_t physicalIndex = logi->second.physicalIndex;
1339 			indexUse = &(logi->second);
1340 			// check size
1341 			if (logi->second.currentSize < requestedSize)
1342 			{
1343 				// init buffer entry wasn't big enough; could be a mistake on the part
1344 				// of the original use, or perhaps a variable length we can't predict
1345 				// until first actual runtime use e.g. world matrix array
1346 				size_t insertCount = requestedSize - logi->second.currentSize;
1347 				FloatConstantList::iterator insertPos = mFloatConstants.begin();
1348 				std::advance(insertPos, physicalIndex);
1349 				mFloatConstants.insert(insertPos, insertCount, 0.0f);
1350 				// shift all physical positions after this one
1351 				for (GpuLogicalIndexUseMap::iterator i = mFloatLogicalToPhysical->map.begin();
1352 					i != mFloatLogicalToPhysical->map.end(); ++i)
1353 				{
1354 					if (i->second.physicalIndex > physicalIndex)
1355 						i->second.physicalIndex += insertCount;
1356 				}
1357 				mFloatLogicalToPhysical->bufferSize += insertCount;
1358 				for (AutoConstantList::iterator i = mAutoConstants.begin();
1359 					i != mAutoConstants.end(); ++i)
1360 				{
1361                     const GpuProgramParameters::AutoConstantDefinition* def = getAutoConstantDefinition(i->paramType);
1362 					if (i->physicalIndex > physicalIndex &&
1363 						def && def->elementType == ET_REAL)
1364 					{
1365 						i->physicalIndex += insertCount;
1366 					}
1367 				}
1368 				if (!mNamedConstants.isNull())
1369 				{
1370 					for (GpuConstantDefinitionMap::iterator i = mNamedConstants->map.begin();
1371 						i != mNamedConstants->map.end(); ++i)
1372 					{
1373 						if (i->second.isFloat() && i->second.physicalIndex > physicalIndex)
1374 							i->second.physicalIndex += insertCount;
1375 					}
1376 					mNamedConstants->floatBufferSize += insertCount;
1377 				}
1378 
1379 				logi->second.currentSize += insertCount;
1380 			}
1381 		}
1382 
1383 		if (indexUse)
1384 			indexUse->variability = variability;
1385 
1386 		return indexUse;
1387 
1388 	}
1389 	//---------------------------------------------------------------------
_getDoubleConstantLogicalIndexUse(size_t logicalIndex,size_t requestedSize,uint16 variability)1390 	GpuLogicalIndexUse* GpuProgramParameters::_getDoubleConstantLogicalIndexUse(
1391                    size_t logicalIndex, size_t requestedSize, uint16 variability)
1392 	{
1393 		if (mDoubleLogicalToPhysical.isNull())
1394 			return 0;
1395 
1396 		GpuLogicalIndexUse* indexUse = 0;
1397 		OGRE_LOCK_MUTEX(mDoubleLogicalToPhysical->mutex);
1398 
1399         GpuLogicalIndexUseMap::iterator logi = mDoubleLogicalToPhysical->map.find(logicalIndex);
1400 		if (logi == mDoubleLogicalToPhysical->map.end())
1401 		{
1402 			if (requestedSize)
1403 			{
1404 				size_t physicalIndex = mDoubleConstants.size();
1405 
1406 				// Expand at buffer end
1407 				mDoubleConstants.insert(mDoubleConstants.end(), requestedSize, 0.0f);
1408 
1409 				// Record extended size for future GPU params re-using this information
1410 				mDoubleLogicalToPhysical->bufferSize = mDoubleConstants.size();
1411 
1412 				// low-level programs will not know about mapping ahead of time, so
1413 				// populate it. Other params objects will be able to just use this
1414 				// accepted mapping since the constant structure will be the same
1415 
1416 				// Set up a mapping for all items in the count
1417 				size_t currPhys = physicalIndex;
1418 				size_t count = requestedSize / 4;
1419 				GpuLogicalIndexUseMap::iterator insertedIterator;
1420 
1421 				for (size_t logicalNum = 0; logicalNum < count; ++logicalNum)
1422 				{
1423 					GpuLogicalIndexUseMap::iterator it =
1424                     mDoubleLogicalToPhysical->map.insert(
1425                         GpuLogicalIndexUseMap::value_type(
1426                           logicalIndex + logicalNum,
1427                           GpuLogicalIndexUse(currPhys, requestedSize, variability))).first;
1428 					currPhys += 4;
1429 
1430 					if (logicalNum == 0)
1431 						insertedIterator = it;
1432 				}
1433 
1434 				indexUse = &(insertedIterator->second);
1435 			}
1436 			else
1437 			{
1438 				// no match & ignore
1439 				return 0;
1440 			}
1441 
1442 		}
1443 		else
1444 		{
1445 			size_t physicalIndex = logi->second.physicalIndex;
1446 			indexUse = &(logi->second);
1447 			// check size
1448 			if (logi->second.currentSize < requestedSize)
1449 			{
1450 				// init buffer entry wasn't big enough; could be a mistake on the part
1451 				// of the original use, or perhaps a variable length we can't predict
1452 				// until first actual runtime use e.g. world matrix array
1453 				size_t insertCount = requestedSize - logi->second.currentSize;
1454 				DoubleConstantList::iterator insertPos = mDoubleConstants.begin();
1455 				std::advance(insertPos, physicalIndex);
1456 				mDoubleConstants.insert(insertPos, insertCount, 0.0f);
1457 				// shift all physical positions after this one
1458 				for (GpuLogicalIndexUseMap::iterator i = mDoubleLogicalToPhysical->map.begin();
1459                      i != mDoubleLogicalToPhysical->map.end(); ++i)
1460 				{
1461 					if (i->second.physicalIndex > physicalIndex)
1462 						i->second.physicalIndex += insertCount;
1463 				}
1464 				mDoubleLogicalToPhysical->bufferSize += insertCount;
1465 				for (AutoConstantList::iterator i = mAutoConstants.begin();
1466                      i != mAutoConstants.end(); ++i)
1467 				{
1468                     const GpuProgramParameters::AutoConstantDefinition* def = getAutoConstantDefinition(i->paramType);
1469 					if (i->physicalIndex > physicalIndex &&
1470 						def && def->elementType == ET_REAL)
1471 					{
1472 						i->physicalIndex += insertCount;
1473 					}
1474 				}
1475 				if (!mNamedConstants.isNull())
1476 				{
1477 					for (GpuConstantDefinitionMap::iterator i = mNamedConstants->map.begin();
1478                          i != mNamedConstants->map.end(); ++i)
1479 					{
1480 						if (i->second.isDouble() && i->second.physicalIndex > physicalIndex)
1481 							i->second.physicalIndex += insertCount;
1482 					}
1483 					mNamedConstants->doubleBufferSize += insertCount;
1484 				}
1485 
1486 				logi->second.currentSize += insertCount;
1487 			}
1488 		}
1489 
1490 		if (indexUse)
1491 			indexUse->variability = variability;
1492 
1493 		return indexUse;
1494 
1495 	}
1496 	//---------------------------------------------------------------------()
_getIntConstantLogicalIndexUse(size_t logicalIndex,size_t requestedSize,uint16 variability)1497 	GpuLogicalIndexUse* GpuProgramParameters::_getIntConstantLogicalIndexUse(size_t logicalIndex, size_t requestedSize, uint16 variability)
1498 	{
1499 		if (mIntLogicalToPhysical.isNull())
1500 			OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
1501 			"This is not a low-level parameter parameter object",
1502 			"GpuProgramParameters::_getIntConstantPhysicalIndex");
1503 
1504 		GpuLogicalIndexUse* indexUse = 0;
1505 		OGRE_LOCK_MUTEX(mIntLogicalToPhysical->mutex);
1506 
1507 			GpuLogicalIndexUseMap::iterator logi = mIntLogicalToPhysical->map.find(logicalIndex);
1508 		if (logi == mIntLogicalToPhysical->map.end())
1509 		{
1510 			if (requestedSize)
1511 			{
1512 				size_t physicalIndex = mIntConstants.size();
1513 
1514 				// Expand at buffer end
1515 				mIntConstants.insert(mIntConstants.end(), requestedSize, 0);
1516 
1517 				// Record extended size for future GPU params re-using this information
1518 				mIntLogicalToPhysical->bufferSize = mIntConstants.size();
1519 
1520 				// low-level programs will not know about mapping ahead of time, so
1521 				// populate it. Other params objects will be able to just use this
1522 				// accepted mapping since the constant structure will be the same
1523 
1524 				// Set up a mapping for all items in the count
1525 				size_t currPhys = physicalIndex;
1526 				size_t count = requestedSize / 4;
1527 				GpuLogicalIndexUseMap::iterator insertedIterator;
1528 				for (size_t logicalNum = 0; logicalNum < count; ++logicalNum)
1529 				{
1530 					GpuLogicalIndexUseMap::iterator it =
1531 						mIntLogicalToPhysical->map.insert(
1532 						GpuLogicalIndexUseMap::value_type(
1533 						logicalIndex + logicalNum,
1534 						GpuLogicalIndexUse(currPhys, requestedSize, variability))).first;
1535 					if (logicalNum == 0)
1536 						insertedIterator = it;
1537 					currPhys += 4;
1538 				}
1539 				indexUse = &(insertedIterator->second);
1540 
1541 			}
1542 			else
1543 			{
1544 				// no match
1545 				return 0;
1546 			}
1547 
1548 		}
1549 		else
1550 		{
1551 			size_t physicalIndex = logi->second.physicalIndex;
1552 			indexUse = &(logi->second);
1553 
1554 			// check size
1555 			if (logi->second.currentSize < requestedSize)
1556 			{
1557 				// init buffer entry wasn't big enough; could be a mistake on the part
1558 				// of the original use, or perhaps a variable length we can't predict
1559 				// until first actual runtime use e.g. world matrix array
1560 				size_t insertCount = requestedSize - logi->second.currentSize;
1561 				IntConstantList::iterator insertPos = mIntConstants.begin();
1562 				std::advance(insertPos, physicalIndex);
1563 				mIntConstants.insert(insertPos, insertCount, 0);
1564 				// shift all physical positions after this one
1565 				for (GpuLogicalIndexUseMap::iterator i = mIntLogicalToPhysical->map.begin();
1566 					i != mIntLogicalToPhysical->map.end(); ++i)
1567 				{
1568 					if (i->second.physicalIndex > physicalIndex)
1569 						i->second.physicalIndex += insertCount;
1570 				}
1571 				mIntLogicalToPhysical->bufferSize += insertCount;
1572 				for (AutoConstantList::iterator i = mAutoConstants.begin();
1573 					i != mAutoConstants.end(); ++i)
1574 				{
1575                     const GpuProgramParameters::AutoConstantDefinition* def = getAutoConstantDefinition(i->paramType);
1576 					if (i->physicalIndex > physicalIndex &&
1577 						def && def->elementType == ET_INT)
1578 					{
1579 						i->physicalIndex += insertCount;
1580 					}
1581 				}
1582 				if (!mNamedConstants.isNull())
1583 				{
1584 					for (GpuConstantDefinitionMap::iterator i = mNamedConstants->map.begin();
1585 						i != mNamedConstants->map.end(); ++i)
1586 					{
1587 						if (!i->second.isFloat() && i->second.physicalIndex > physicalIndex)
1588 							i->second.physicalIndex += insertCount;
1589 					}
1590 					mNamedConstants->intBufferSize += insertCount;
1591 				}
1592 
1593 				logi->second.currentSize += insertCount;
1594 			}
1595 		}
1596 
1597 		if (indexUse)
1598 			indexUse->variability = variability;
1599 
1600 		return indexUse;
1601 
1602 	}
1603 	//-----------------------------------------------------------------------------
_getFloatConstantPhysicalIndex(size_t logicalIndex,size_t requestedSize,uint16 variability)1604 	size_t GpuProgramParameters::_getFloatConstantPhysicalIndex(
1605 		size_t logicalIndex, size_t requestedSize, uint16 variability)
1606 	{
1607 		GpuLogicalIndexUse* indexUse = _getFloatConstantLogicalIndexUse(logicalIndex, requestedSize, variability);
1608 		return indexUse ? indexUse->physicalIndex : 0;
1609 	}
1610 	//-----------------------------------------------------------------------------
_getDoubleConstantPhysicalIndex(size_t logicalIndex,size_t requestedSize,uint16 variability)1611 	size_t GpuProgramParameters::_getDoubleConstantPhysicalIndex(
1612         size_t logicalIndex, size_t requestedSize, uint16 variability)
1613 	{
1614 		GpuLogicalIndexUse* indexUse = _getDoubleConstantLogicalIndexUse(logicalIndex, requestedSize, variability);
1615 		return indexUse ? indexUse->physicalIndex : 0;
1616 	}
1617 	//-----------------------------------------------------------------------------
_getIntConstantPhysicalIndex(size_t logicalIndex,size_t requestedSize,uint16 variability)1618 	size_t GpuProgramParameters::_getIntConstantPhysicalIndex(
1619 		size_t logicalIndex, size_t requestedSize, uint16 variability)
1620 	{
1621 		GpuLogicalIndexUse* indexUse = _getIntConstantLogicalIndexUse(logicalIndex, requestedSize, variability);
1622 		return indexUse ? indexUse->physicalIndex : 0;
1623 	}
1624 	//-----------------------------------------------------------------------------
getFloatLogicalIndexForPhysicalIndex(size_t physicalIndex)1625 	size_t GpuProgramParameters::getFloatLogicalIndexForPhysicalIndex(size_t physicalIndex)
1626 	{
1627 		// perhaps build a reverse map of this sometime (shared in GpuProgram)
1628 		for (GpuLogicalIndexUseMap::iterator i = mFloatLogicalToPhysical->map.begin();
1629 			i != mFloatLogicalToPhysical->map.end(); ++i)
1630 		{
1631 			if (i->second.physicalIndex == physicalIndex)
1632 				return i->first;
1633 		}
1634 		return std::numeric_limits<size_t>::max();
1635 
1636 	}
1637 	//-----------------------------------------------------------------------------
getDoubleLogicalIndexForPhysicalIndex(size_t physicalIndex)1638 	size_t GpuProgramParameters::getDoubleLogicalIndexForPhysicalIndex(size_t physicalIndex)
1639 	{
1640 		// perhaps build a reverse map of this sometime (shared in GpuProgram)
1641 		for (GpuLogicalIndexUseMap::iterator i = mDoubleLogicalToPhysical->map.begin();
1642              i != mDoubleLogicalToPhysical->map.end(); ++i)
1643 		{
1644 			if (i->second.physicalIndex == physicalIndex)
1645 				return i->first;
1646 		}
1647 		return std::numeric_limits<size_t>::max();
1648 	}
1649 	//-----------------------------------------------------------------------------
getIntLogicalIndexForPhysicalIndex(size_t physicalIndex)1650 	size_t GpuProgramParameters::getIntLogicalIndexForPhysicalIndex(size_t physicalIndex)
1651 	{
1652 		// perhaps build a reverse map of this sometime (shared in GpuProgram)
1653 		for (GpuLogicalIndexUseMap::iterator i = mIntLogicalToPhysical->map.begin();
1654 			i != mIntLogicalToPhysical->map.end(); ++i)
1655 		{
1656 			if (i->second.physicalIndex == physicalIndex)
1657 				return i->first;
1658 		}
1659 		return std::numeric_limits<size_t>::max();
1660 
1661 	}
1662 	//-----------------------------------------------------------------------------
getConstantDefinitionIterator(void) const1663 	GpuConstantDefinitionIterator GpuProgramParameters::getConstantDefinitionIterator(void) const
1664 	{
1665 		if (mNamedConstants.isNull())
1666 			OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
1667 			"This params object is not based on a program with named parameters.",
1668 			"GpuProgramParameters::getConstantDefinitionIterator");
1669 
1670 		return GpuConstantDefinitionIterator(mNamedConstants->map.begin(),
1671 			mNamedConstants->map.end());
1672 
1673 	}
1674 	//-----------------------------------------------------------------------------
getConstantDefinitions() const1675 	const GpuNamedConstants& GpuProgramParameters::getConstantDefinitions() const
1676 	{
1677 		if (mNamedConstants.isNull())
1678 			OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
1679 			"This params object is not based on a program with named parameters.",
1680 			"GpuProgramParameters::getConstantDefinitionIterator");
1681 
1682 		return *mNamedConstants;
1683 	}
1684 	//-----------------------------------------------------------------------------
getConstantDefinition(const String & name) const1685 	const GpuConstantDefinition& GpuProgramParameters::getConstantDefinition(const String& name) const
1686 	{
1687 		if (mNamedConstants.isNull())
1688 			OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
1689 			"This params object is not based on a program with named parameters.",
1690 			"GpuProgramParameters::getConstantDefinitionIterator");
1691 
1692 
1693 		// locate, and throw exception if not found
1694 		const GpuConstantDefinition* def = _findNamedConstantDefinition(name, true);
1695 
1696 		return *def;
1697 
1698 	}
1699 	//-----------------------------------------------------------------------------
1700 	const GpuConstantDefinition*
_findNamedConstantDefinition(const String & name,bool throwExceptionIfNotFound) const1701 		GpuProgramParameters::_findNamedConstantDefinition(const String& name,
1702 		bool throwExceptionIfNotFound) const
1703 	{
1704 		if (mNamedConstants.isNull())
1705 		{
1706 			if (throwExceptionIfNotFound)
1707 				OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
1708 				"Named constants have not been initialised, perhaps a compile error.",
1709 				"GpuProgramParameters::_findNamedConstantDefinition");
1710 			return 0;
1711 		}
1712 
1713 		GpuConstantDefinitionMap::const_iterator i = mNamedConstants->map.find(name);
1714 		if (i == mNamedConstants->map.end())
1715 		{
1716 			if (throwExceptionIfNotFound)
1717 				OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
1718 				"Parameter called " + name + " does not exist. ",
1719 				"GpuProgramParameters::_findNamedConstantDefinition");
1720 			return 0;
1721 		}
1722 		else
1723 		{
1724 			return &(i->second);
1725 		}
1726 	}
1727 	//-----------------------------------------------------------------------------
setAutoConstant(size_t index,AutoConstantType acType,size_t extraInfo)1728 	void GpuProgramParameters::setAutoConstant(size_t index, AutoConstantType acType, size_t extraInfo)
1729 	{
1730 		// Get auto constant definition for sizing
1731 		const AutoConstantDefinition* autoDef = getAutoConstantDefinition(acType);
1732 
1733         if(!autoDef)
1734             OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "No constant definition found for type " +
1735                         StringConverter::toString(acType),
1736                         "GpuProgramParameters::setAutoConstant");
1737 
1738         // round up to nearest multiple of 4
1739 		size_t sz = autoDef->elementCount;
1740 		if (sz % 4 > 0)
1741 		{
1742 			sz += 4 - (sz % 4);
1743 		}
1744 
1745 		GpuLogicalIndexUse* indexUse = _getFloatConstantLogicalIndexUse(index, sz, deriveVariability(acType));
1746 
1747         if(indexUse)
1748             _setRawAutoConstant(indexUse->physicalIndex, acType, extraInfo, indexUse->variability, sz);
1749 	}
1750 	//-----------------------------------------------------------------------------
_setRawAutoConstant(size_t physicalIndex,AutoConstantType acType,size_t extraInfo,uint16 variability,size_t elementSize)1751 	void GpuProgramParameters::_setRawAutoConstant(size_t physicalIndex,
1752 		AutoConstantType acType, size_t extraInfo, uint16 variability, size_t elementSize)
1753 	{
1754 		// update existing index if it exists
1755 		bool found = false;
1756 		for (AutoConstantList::iterator i = mAutoConstants.begin();
1757 			i != mAutoConstants.end(); ++i)
1758 		{
1759 			if (i->physicalIndex == physicalIndex)
1760 			{
1761 				i->paramType = acType;
1762 				i->data = extraInfo;
1763 				i->elementCount = elementSize;
1764 				i->variability = variability;
1765 				found = true;
1766 				break;
1767 			}
1768 		}
1769 		if (!found)
1770 			mAutoConstants.push_back(AutoConstantEntry(acType, physicalIndex, extraInfo, variability, elementSize));
1771 
1772 		mCombinedVariability |= variability;
1773 
1774 
1775 	}
1776 	//-----------------------------------------------------------------------------
setAutoConstant(size_t index,AutoConstantType acType,uint16 extraInfo1,uint16 extraInfo2)1777 	void GpuProgramParameters::setAutoConstant(size_t index, AutoConstantType acType, uint16 extraInfo1, uint16 extraInfo2)
1778 	{
1779 		size_t extraInfo = (size_t)extraInfo1 | ((size_t)extraInfo2) << 16;
1780 
1781 		// Get auto constant definition for sizing
1782 		const AutoConstantDefinition* autoDef = getAutoConstantDefinition(acType);
1783 
1784         if(!autoDef)
1785             OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "No constant definition found for type " +
1786                         StringConverter::toString(acType),
1787                         "GpuProgramParameters::setAutoConstant");
1788 
1789 		// round up to nearest multiple of 4
1790 		size_t sz = autoDef->elementCount;
1791 		if (sz % 4 > 0)
1792 		{
1793 			sz += 4 - (sz % 4);
1794 		}
1795 
1796 		GpuLogicalIndexUse* indexUse = _getFloatConstantLogicalIndexUse(index, sz, deriveVariability(acType));
1797 
1798 		_setRawAutoConstant(indexUse->physicalIndex, acType, extraInfo, indexUse->variability, sz);
1799 	}
1800 	//-----------------------------------------------------------------------------
_setRawAutoConstantReal(size_t physicalIndex,AutoConstantType acType,Real rData,uint16 variability,size_t elementSize)1801 	void GpuProgramParameters::_setRawAutoConstantReal(size_t physicalIndex,
1802 		AutoConstantType acType, Real rData, uint16 variability, size_t elementSize)
1803 	{
1804 		// update existing index if it exists
1805 		bool found = false;
1806 		for (AutoConstantList::iterator i = mAutoConstants.begin();
1807 			i != mAutoConstants.end(); ++i)
1808 		{
1809 			if (i->physicalIndex == physicalIndex)
1810 			{
1811 				i->paramType = acType;
1812 				i->fData = rData;
1813 				i->elementCount = elementSize;
1814 				i->variability = variability;
1815 				found = true;
1816 				break;
1817 			}
1818 		}
1819 		if (!found)
1820 			mAutoConstants.push_back(AutoConstantEntry(acType, physicalIndex, rData, variability, elementSize));
1821 
1822 		mCombinedVariability |= variability;
1823 	}
1824 	//-----------------------------------------------------------------------------
clearAutoConstant(size_t index)1825 	void GpuProgramParameters::clearAutoConstant(size_t index)
1826 	{
1827 		GpuLogicalIndexUse* indexUse = _getFloatConstantLogicalIndexUse(index, 0, GPV_GLOBAL);
1828 
1829 		if (indexUse)
1830 		{
1831 			indexUse->variability = GPV_GLOBAL;
1832 			size_t physicalIndex = indexUse->physicalIndex;
1833 			// update existing index if it exists
1834 			for (AutoConstantList::iterator i = mAutoConstants.begin();
1835 				i != mAutoConstants.end(); ++i)
1836 			{
1837 				if (i->physicalIndex == physicalIndex)
1838 				{
1839 					mAutoConstants.erase(i);
1840 					break;
1841 				}
1842 			}
1843 		}
1844 	}
1845 	//-----------------------------------------------------------------------------
clearNamedAutoConstant(const String & name)1846 	void GpuProgramParameters::clearNamedAutoConstant(const String& name)
1847 	{
1848 		const GpuConstantDefinition* def = _findNamedConstantDefinition(name);
1849 		if (def)
1850 		{
1851 			def->variability = GPV_GLOBAL;
1852 
1853 			// Autos are always floating point
1854 			if (def->isFloat())
1855 			{
1856 				for (AutoConstantList::iterator i = mAutoConstants.begin();
1857 					i != mAutoConstants.end(); ++i)
1858 				{
1859 					if (i->physicalIndex == def->physicalIndex)
1860 					{
1861 						mAutoConstants.erase(i);
1862 						break;
1863 					}
1864 				}
1865 			}
1866 
1867 		}
1868 	}
1869 	//-----------------------------------------------------------------------------
clearAutoConstants(void)1870 	void GpuProgramParameters::clearAutoConstants(void)
1871 	{
1872 		mAutoConstants.clear();
1873 		mCombinedVariability = GPV_GLOBAL;
1874 	}
1875 	//-----------------------------------------------------------------------------
getAutoConstantIterator(void) const1876 	GpuProgramParameters::AutoConstantIterator GpuProgramParameters::getAutoConstantIterator(void) const
1877 	{
1878 		return AutoConstantIterator(mAutoConstants.begin(), mAutoConstants.end());
1879 	}
1880 	//-----------------------------------------------------------------------------
setAutoConstantReal(size_t index,AutoConstantType acType,Real rData)1881 	void GpuProgramParameters::setAutoConstantReal(size_t index, AutoConstantType acType, Real rData)
1882 	{
1883 		// Get auto constant definition for sizing
1884 		const AutoConstantDefinition* autoDef = getAutoConstantDefinition(acType);
1885 
1886         if(!autoDef)
1887             OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "No constant definition found for type " +
1888                         StringConverter::toString(acType),
1889                         "GpuProgramParameters::setAutoConstantReal");
1890 
1891 		// round up to nearest multiple of 4
1892 		size_t sz = autoDef->elementCount;
1893 		if (sz % 4 > 0)
1894 		{
1895 			sz += 4 - (sz % 4);
1896 		}
1897 
1898 		GpuLogicalIndexUse* indexUse = _getFloatConstantLogicalIndexUse(index, sz, deriveVariability(acType));
1899 
1900 		_setRawAutoConstantReal(indexUse->physicalIndex, acType, rData, indexUse->variability, sz);
1901 	}
1902 	//-----------------------------------------------------------------------------
1903 
1904 	//-----------------------------------------------------------------------------
_updateAutoParams(const AutoParamDataSource * source,uint16 mask)1905 	void GpuProgramParameters::_updateAutoParams(const AutoParamDataSource* source, uint16 mask)
1906 	{
1907 		// abort early if no autos
1908 		if (!hasAutoConstants()) return;
1909 		// abort early if variability doesn't match any param
1910 		if (!(mask & mCombinedVariability))
1911 			return;
1912 
1913 		size_t index;
1914 		size_t numMatrices;
1915 		const Matrix4* pMatrix;
1916 		size_t m;
1917 		Vector3 vec3;
1918 		Vector4 vec4;
1919 		Matrix3 m3;
1920 		Matrix4 scaleM;
1921 		DualQuaternion dQuat;
1922 
1923 		mActivePassIterationIndex = std::numeric_limits<size_t>::max();
1924 
1925 		// Autoconstant index is not a physical index
1926 		for (AutoConstantList::const_iterator i = mAutoConstants.begin(); i != mAutoConstants.end(); ++i)
1927 		{
1928 			// Only update needed slots
1929 			if (i->variability & mask)
1930 			{
1931 
1932 				switch(i->paramType)
1933 				{
1934 				case ACT_VIEW_MATRIX:
1935 					_writeRawConstant(i->physicalIndex, source->getViewMatrix(),i->elementCount);
1936 					break;
1937 				case ACT_INVERSE_VIEW_MATRIX:
1938 					_writeRawConstant(i->physicalIndex, source->getInverseViewMatrix(),i->elementCount);
1939 					break;
1940 				case ACT_TRANSPOSE_VIEW_MATRIX:
1941 					_writeRawConstant(i->physicalIndex, source->getTransposeViewMatrix(),i->elementCount);
1942 					break;
1943 				case ACT_INVERSE_TRANSPOSE_VIEW_MATRIX:
1944 					_writeRawConstant(i->physicalIndex, source->getInverseTransposeViewMatrix(),i->elementCount);
1945 					break;
1946 
1947 				case ACT_PROJECTION_MATRIX:
1948 					_writeRawConstant(i->physicalIndex, source->getProjectionMatrix(),i->elementCount);
1949 					break;
1950 				case ACT_INVERSE_PROJECTION_MATRIX:
1951 					_writeRawConstant(i->physicalIndex, source->getInverseProjectionMatrix(),i->elementCount);
1952 					break;
1953 				case ACT_TRANSPOSE_PROJECTION_MATRIX:
1954 					_writeRawConstant(i->physicalIndex, source->getTransposeProjectionMatrix(),i->elementCount);
1955 					break;
1956 				case ACT_INVERSE_TRANSPOSE_PROJECTION_MATRIX:
1957 					_writeRawConstant(i->physicalIndex, source->getInverseTransposeProjectionMatrix(),i->elementCount);
1958 					break;
1959 
1960 				case ACT_VIEWPROJ_MATRIX:
1961 					_writeRawConstant(i->physicalIndex, source->getViewProjectionMatrix(),i->elementCount);
1962 					break;
1963 				case ACT_INVERSE_VIEWPROJ_MATRIX:
1964 					_writeRawConstant(i->physicalIndex, source->getInverseViewProjMatrix(),i->elementCount);
1965 					break;
1966 				case ACT_TRANSPOSE_VIEWPROJ_MATRIX:
1967 					_writeRawConstant(i->physicalIndex, source->getTransposeViewProjMatrix(),i->elementCount);
1968 					break;
1969 				case ACT_INVERSE_TRANSPOSE_VIEWPROJ_MATRIX:
1970 					_writeRawConstant(i->physicalIndex, source->getInverseTransposeViewProjMatrix(),i->elementCount);
1971 					break;
1972 				case ACT_RENDER_TARGET_FLIPPING:
1973 					_writeRawConstant(i->physicalIndex, source->getCurrentRenderTarget()->requiresTextureFlipping() ? -1.f : +1.f);
1974 					break;
1975 				case ACT_VERTEX_WINDING:
1976 					{
1977 						RenderSystem* rsys = Root::getSingleton().getRenderSystem();
1978 						_writeRawConstant(i->physicalIndex, rsys->getInvertVertexWinding() ? -1.f : +1.f);
1979 					}
1980 					break;
1981 
1982 					// NB ambient light still here because it's not related to a specific light
1983 				case ACT_AMBIENT_LIGHT_COLOUR:
1984 					_writeRawConstant(i->physicalIndex, source->getAmbientLightColour(),
1985 						i->elementCount);
1986 					break;
1987 				case ACT_DERIVED_AMBIENT_LIGHT_COLOUR:
1988 					_writeRawConstant(i->physicalIndex, source->getDerivedAmbientLightColour(),
1989 						i->elementCount);
1990 					break;
1991 				case ACT_DERIVED_SCENE_COLOUR:
1992 					_writeRawConstant(i->physicalIndex, source->getDerivedSceneColour(),
1993 						i->elementCount);
1994 					break;
1995 
1996 				case ACT_FOG_COLOUR:
1997 					_writeRawConstant(i->physicalIndex, source->getFogColour());
1998 					break;
1999 				case ACT_FOG_PARAMS:
2000 					_writeRawConstant(i->physicalIndex, source->getFogParams(), i->elementCount);
2001 					break;
2002 
2003 				case ACT_SURFACE_AMBIENT_COLOUR:
2004 					_writeRawConstant(i->physicalIndex, source->getSurfaceAmbientColour(),
2005 						i->elementCount);
2006 					break;
2007 				case ACT_SURFACE_DIFFUSE_COLOUR:
2008 					_writeRawConstant(i->physicalIndex, source->getSurfaceDiffuseColour(),
2009 						i->elementCount);
2010 					break;
2011 				case ACT_SURFACE_SPECULAR_COLOUR:
2012 					_writeRawConstant(i->physicalIndex, source->getSurfaceSpecularColour(),
2013 						i->elementCount);
2014 					break;
2015 				case ACT_SURFACE_EMISSIVE_COLOUR:
2016 					_writeRawConstant(i->physicalIndex, source->getSurfaceEmissiveColour(),
2017 						i->elementCount);
2018 					break;
2019 				case ACT_SURFACE_SHININESS:
2020 					_writeRawConstant(i->physicalIndex, source->getSurfaceShininess());
2021 					break;
2022 				case ACT_SURFACE_ALPHA_REJECTION_VALUE:
2023 					_writeRawConstant(i->physicalIndex, source->getSurfaceAlphaRejectionValue());
2024 					break;
2025 
2026 				case ACT_CAMERA_POSITION:
2027 					_writeRawConstant(i->physicalIndex, source->getCameraPosition(), i->elementCount);
2028 					break;
2029 				case ACT_TIME:
2030 					_writeRawConstant(i->physicalIndex, source->getTime() * i->fData);
2031 					break;
2032 				case ACT_TIME_0_X:
2033 					_writeRawConstant(i->physicalIndex, source->getTime_0_X(i->fData));
2034 					break;
2035 				case ACT_COSTIME_0_X:
2036 					_writeRawConstant(i->physicalIndex, source->getCosTime_0_X(i->fData));
2037 					break;
2038 				case ACT_SINTIME_0_X:
2039 					_writeRawConstant(i->physicalIndex, source->getSinTime_0_X(i->fData));
2040 					break;
2041 				case ACT_TANTIME_0_X:
2042 					_writeRawConstant(i->physicalIndex, source->getTanTime_0_X(i->fData));
2043 					break;
2044 				case ACT_TIME_0_X_PACKED:
2045 					_writeRawConstant(i->physicalIndex, source->getTime_0_X_packed(i->fData), i->elementCount);
2046 					break;
2047 				case ACT_TIME_0_1:
2048 					_writeRawConstant(i->physicalIndex, source->getTime_0_1(i->fData));
2049 					break;
2050 				case ACT_COSTIME_0_1:
2051 					_writeRawConstant(i->physicalIndex, source->getCosTime_0_1(i->fData));
2052 					break;
2053 				case ACT_SINTIME_0_1:
2054 					_writeRawConstant(i->physicalIndex, source->getSinTime_0_1(i->fData));
2055 					break;
2056 				case ACT_TANTIME_0_1:
2057 					_writeRawConstant(i->physicalIndex, source->getTanTime_0_1(i->fData));
2058 					break;
2059 				case ACT_TIME_0_1_PACKED:
2060 					_writeRawConstant(i->physicalIndex, source->getTime_0_1_packed(i->fData), i->elementCount);
2061 					break;
2062 				case ACT_TIME_0_2PI:
2063 					_writeRawConstant(i->physicalIndex, source->getTime_0_2Pi(i->fData));
2064 					break;
2065 				case ACT_COSTIME_0_2PI:
2066 					_writeRawConstant(i->physicalIndex, source->getCosTime_0_2Pi(i->fData));
2067 					break;
2068 				case ACT_SINTIME_0_2PI:
2069 					_writeRawConstant(i->physicalIndex, source->getSinTime_0_2Pi(i->fData));
2070 					break;
2071 				case ACT_TANTIME_0_2PI:
2072 					_writeRawConstant(i->physicalIndex, source->getTanTime_0_2Pi(i->fData));
2073 					break;
2074 				case ACT_TIME_0_2PI_PACKED:
2075 					_writeRawConstant(i->physicalIndex, source->getTime_0_2Pi_packed(i->fData), i->elementCount);
2076 					break;
2077 				case ACT_FRAME_TIME:
2078 					_writeRawConstant(i->physicalIndex, source->getFrameTime() * i->fData);
2079 					break;
2080 				case ACT_FPS:
2081 					_writeRawConstant(i->physicalIndex, source->getFPS());
2082 					break;
2083 				case ACT_VIEWPORT_WIDTH:
2084 					_writeRawConstant(i->physicalIndex, source->getViewportWidth());
2085 					break;
2086 				case ACT_VIEWPORT_HEIGHT:
2087 					_writeRawConstant(i->physicalIndex, source->getViewportHeight());
2088 					break;
2089 				case ACT_INVERSE_VIEWPORT_WIDTH:
2090 					_writeRawConstant(i->physicalIndex, source->getInverseViewportWidth());
2091 					break;
2092 				case ACT_INVERSE_VIEWPORT_HEIGHT:
2093 					_writeRawConstant(i->physicalIndex, source->getInverseViewportHeight());
2094 					break;
2095 				case ACT_VIEWPORT_SIZE:
2096 					_writeRawConstant(i->physicalIndex, Vector4(
2097 						source->getViewportWidth(),
2098 						source->getViewportHeight(),
2099 						source->getInverseViewportWidth(),
2100 						source->getInverseViewportHeight()), i->elementCount);
2101 					break;
2102 				case ACT_TEXEL_OFFSETS:
2103 					{
2104 						RenderSystem* rsys = Root::getSingleton().getRenderSystem();
2105 						_writeRawConstant(i->physicalIndex, Vector4(
2106 							rsys->getHorizontalTexelOffset(),
2107 							rsys->getVerticalTexelOffset(),
2108 							rsys->getHorizontalTexelOffset() * source->getInverseViewportWidth(),
2109 							rsys->getVerticalTexelOffset() * source->getInverseViewportHeight()),
2110 							i->elementCount);
2111 					}
2112 					break;
2113 				case ACT_TEXTURE_SIZE:
2114 					_writeRawConstant(i->physicalIndex, source->getTextureSize(i->data), i->elementCount);
2115 					break;
2116 				case ACT_INVERSE_TEXTURE_SIZE:
2117 					_writeRawConstant(i->physicalIndex, source->getInverseTextureSize(i->data), i->elementCount);
2118 					break;
2119 				case ACT_PACKED_TEXTURE_SIZE:
2120 					_writeRawConstant(i->physicalIndex, source->getPackedTextureSize(i->data), i->elementCount);
2121 					break;
2122 				case ACT_SCENE_DEPTH_RANGE:
2123 					_writeRawConstant(i->physicalIndex, source->getSceneDepthRange(), i->elementCount);
2124 					break;
2125 				case ACT_VIEW_DIRECTION:
2126 					_writeRawConstant(i->physicalIndex, source->getViewDirection());
2127 					break;
2128 				case ACT_VIEW_SIDE_VECTOR:
2129 					_writeRawConstant(i->physicalIndex, source->getViewSideVector());
2130 					break;
2131 				case ACT_VIEW_UP_VECTOR:
2132 					_writeRawConstant(i->physicalIndex, source->getViewUpVector());
2133 					break;
2134 				case ACT_FOV:
2135 					_writeRawConstant(i->physicalIndex, source->getFOV());
2136 					break;
2137 				case ACT_NEAR_CLIP_DISTANCE:
2138 					_writeRawConstant(i->physicalIndex, source->getNearClipDistance());
2139 					break;
2140 				case ACT_FAR_CLIP_DISTANCE:
2141 					_writeRawConstant(i->physicalIndex, source->getFarClipDistance());
2142 					break;
2143 				case ACT_PASS_NUMBER:
2144 					_writeRawConstant(i->physicalIndex, (float)source->getPassNumber());
2145 					break;
2146 				case ACT_PASS_ITERATION_NUMBER:
2147 					// this is actually just an initial set-up, it's bound separately, so still global
2148 					_writeRawConstant(i->physicalIndex, 0.0f);
2149 					mActivePassIterationIndex = i->physicalIndex;
2150 					break;
2151 				case ACT_TEXTURE_MATRIX:
2152 					_writeRawConstant(i->physicalIndex, source->getTextureTransformMatrix(i->data),i->elementCount);
2153 					break;
2154 				case ACT_LOD_CAMERA_POSITION:
2155 					_writeRawConstant(i->physicalIndex, source->getLodCameraPosition(), i->elementCount);
2156 					break;
2157 
2158 				case ACT_TEXTURE_WORLDVIEWPROJ_MATRIX:
2159 					// can also be updated in lights
2160 					_writeRawConstant(i->physicalIndex, source->getTextureWorldViewProjMatrix(i->data),i->elementCount);
2161 					break;
2162 				case ACT_TEXTURE_WORLDVIEWPROJ_MATRIX_ARRAY:
2163 					for (size_t l = 0; l < i->data; ++l)
2164 					{
2165 						// can also be updated in lights
2166 						_writeRawConstant(i->physicalIndex + l*i->elementCount,
2167 							source->getTextureWorldViewProjMatrix(l),i->elementCount);
2168 					}
2169 					break;
2170 				case ACT_SPOTLIGHT_WORLDVIEWPROJ_MATRIX:
2171 					_writeRawConstant(i->physicalIndex, source->getSpotlightWorldViewProjMatrix(i->data),i->elementCount);
2172 					break;
2173                 case ACT_SPOTLIGHT_WORLDVIEWPROJ_MATRIX_ARRAY:
2174                     for (size_t l = 0; l < i->data; ++l)
2175                         _writeRawConstant(i->physicalIndex + l*i->elementCount, source->getSpotlightWorldViewProjMatrix(i->data), i->elementCount);
2176                     break;
2177 				case ACT_LIGHT_POSITION_OBJECT_SPACE:
2178 					_writeRawConstant(i->physicalIndex,
2179 						source->getInverseWorldMatrix().transformAffine(
2180 						source->getLightAs4DVector(i->data)),
2181 						i->elementCount);
2182 					break;
2183 				case ACT_LIGHT_DIRECTION_OBJECT_SPACE:
2184 					// We need the inverse of the inverse transpose
2185 					source->getInverseTransposeWorldMatrix().inverse().extract3x3Matrix(m3);
2186 					vec3 = m3 * source->getLightDirection(i->data);
2187 					vec3.normalise();
2188 					// Set as 4D vector for compatibility
2189 					_writeRawConstant(i->physicalIndex, Vector4(vec3.x, vec3.y, vec3.z, 0.0f), i->elementCount);
2190 					break;
2191 				case ACT_LIGHT_DISTANCE_OBJECT_SPACE:
2192 					vec3 = source->getInverseWorldMatrix().transformAffine(source->getLightPosition(i->data));
2193 					_writeRawConstant(i->physicalIndex, vec3.length());
2194 					break;
2195 				case ACT_LIGHT_POSITION_OBJECT_SPACE_ARRAY:
2196 					for (size_t l = 0; l < i->data; ++l)
2197 						_writeRawConstant(i->physicalIndex + l*i->elementCount,
2198 						source->getInverseWorldMatrix().transformAffine(
2199 						source->getLightAs4DVector(l)),
2200 						i->elementCount);
2201 					break;
2202 
2203 				case ACT_LIGHT_DIRECTION_OBJECT_SPACE_ARRAY:
2204 					// We need the inverse of the inverse transpose
2205 					source->getInverseTransposeWorldMatrix().inverse().extract3x3Matrix(m3);
2206 					for (size_t l = 0; l < i->data; ++l)
2207 					{
2208 						vec3 = m3 * source->getLightDirection(l);
2209 						vec3.normalise();
2210 						_writeRawConstant(i->physicalIndex + l*i->elementCount,
2211 							Vector4(vec3.x, vec3.y, vec3.z, 0.0f), i->elementCount);
2212 					}
2213 					break;
2214 
2215 				case ACT_LIGHT_DISTANCE_OBJECT_SPACE_ARRAY:
2216 					for (size_t l = 0; l < i->data; ++l)
2217 					{
2218 						vec3 = source->getInverseWorldMatrix().transformAffine(source->getLightPosition(l));
2219 						_writeRawConstant(i->physicalIndex + l*i->elementCount, vec3.length());
2220 					}
2221 					break;
2222 
2223 				case ACT_WORLD_MATRIX:
2224 					_writeRawConstant(i->physicalIndex, source->getWorldMatrix(),i->elementCount);
2225 					break;
2226 				case ACT_INVERSE_WORLD_MATRIX:
2227 					_writeRawConstant(i->physicalIndex, source->getInverseWorldMatrix(),i->elementCount);
2228 					break;
2229 				case ACT_TRANSPOSE_WORLD_MATRIX:
2230 					_writeRawConstant(i->physicalIndex, source->getTransposeWorldMatrix(),i->elementCount);
2231 					break;
2232 				case ACT_INVERSE_TRANSPOSE_WORLD_MATRIX:
2233 					_writeRawConstant(i->physicalIndex, source->getInverseTransposeWorldMatrix(),i->elementCount);
2234 					break;
2235 
2236 				case ACT_WORLD_MATRIX_ARRAY_3x4:
2237 					// Loop over matrices
2238 					pMatrix = source->getWorldMatrixArray();
2239 					numMatrices = source->getWorldMatrixCount();
2240 					index = i->physicalIndex;
2241 					for (m = 0; m < numMatrices; ++m)
2242 					{
2243 						_writeRawConstants(index, (*pMatrix)[0], 12);
2244 						index += 12;
2245 						++pMatrix;
2246 					}
2247 					break;
2248 				case ACT_WORLD_MATRIX_ARRAY:
2249 					_writeRawConstant(i->physicalIndex, source->getWorldMatrixArray(),
2250 						source->getWorldMatrixCount());
2251 					break;
2252 				case ACT_WORLD_DUALQUATERNION_ARRAY_2x4:
2253 					// Loop over matrices
2254 					pMatrix = source->getWorldMatrixArray();
2255 					numMatrices = source->getWorldMatrixCount();
2256 					index = i->physicalIndex;
2257 					for (m = 0; m < numMatrices; ++m)
2258 					{
2259 						dQuat.fromTransformationMatrix(*pMatrix);
2260 						_writeRawConstants(index, dQuat.ptr(), 8);
2261 						index += 8;
2262 						++pMatrix;
2263 					}
2264 					break;
2265 				case ACT_WORLD_SCALE_SHEAR_MATRIX_ARRAY_3x4:
2266 					// Loop over matrices
2267 					pMatrix = source->getWorldMatrixArray();
2268 					numMatrices = source->getWorldMatrixCount();
2269 					index = i->physicalIndex;
2270 
2271 					scaleM = Matrix4::IDENTITY;
2272 
2273 					for (m = 0; m < numMatrices; ++m)
2274 					{
2275 						//Based on Matrix4::decompostion, but we don't need the rotation or position components
2276 						//but do need the scaling and shearing. Shearing isn't available from Matrix4::decomposition
2277 						assert((*pMatrix).isAffine());
2278 
2279 						(*pMatrix).extract3x3Matrix(m3);
2280 
2281 						Matrix3 matQ;
2282 						Vector3 scale;
2283 
2284 						//vecU is the scaling component with vecU[0] = u01, vecU[1] = u02, vecU[2] = u12
2285 						//vecU[0] is shearing (x,y), vecU[1] is shearing (x,z), and vecU[2] is shearing (y,z)
2286 						//The first component represents the coordinate that is being sheared,
2287 						//while the second component represents the coordinate which performs the shearing.
2288 						Vector3 vecU;
2289 						m3.QDUDecomposition( matQ, scale, vecU );
2290 
2291 						scaleM[0][0] = scale.x;
2292 						scaleM[1][1] = scale.y;
2293 						scaleM[2][2] = scale.z;
2294 
2295 						scaleM[0][1] = vecU[0];
2296 						scaleM[0][2] = vecU[1];
2297 						scaleM[1][2] = vecU[2];
2298 
2299 						_writeRawConstants(index, scaleM[0], 12);
2300 						index += 12;
2301 						++pMatrix;
2302 					}
2303 					break;
2304 				case ACT_WORLDVIEW_MATRIX:
2305 					_writeRawConstant(i->physicalIndex, source->getWorldViewMatrix(),i->elementCount);
2306 					break;
2307 				case ACT_INVERSE_WORLDVIEW_MATRIX:
2308 					_writeRawConstant(i->physicalIndex, source->getInverseWorldViewMatrix(),i->elementCount);
2309 					break;
2310 				case ACT_TRANSPOSE_WORLDVIEW_MATRIX:
2311 					_writeRawConstant(i->physicalIndex, source->getTransposeWorldViewMatrix(),i->elementCount);
2312 					break;
2313 				case ACT_INVERSE_TRANSPOSE_WORLDVIEW_MATRIX:
2314 					_writeRawConstant(i->physicalIndex, source->getInverseTransposeWorldViewMatrix(),i->elementCount);
2315 					break;
2316 
2317 				case ACT_WORLDVIEWPROJ_MATRIX:
2318 					_writeRawConstant(i->physicalIndex, source->getWorldViewProjMatrix(),i->elementCount);
2319 					break;
2320 				case ACT_INVERSE_WORLDVIEWPROJ_MATRIX:
2321 					_writeRawConstant(i->physicalIndex, source->getInverseWorldViewProjMatrix(),i->elementCount);
2322 					break;
2323 				case ACT_TRANSPOSE_WORLDVIEWPROJ_MATRIX:
2324 					_writeRawConstant(i->physicalIndex, source->getTransposeWorldViewProjMatrix(),i->elementCount);
2325 					break;
2326 				case ACT_INVERSE_TRANSPOSE_WORLDVIEWPROJ_MATRIX:
2327 					_writeRawConstant(i->physicalIndex, source->getInverseTransposeWorldViewProjMatrix(),i->elementCount);
2328 					break;
2329 				case ACT_CAMERA_POSITION_OBJECT_SPACE:
2330 					_writeRawConstant(i->physicalIndex, source->getCameraPositionObjectSpace(), i->elementCount);
2331 					break;
2332 				case ACT_LOD_CAMERA_POSITION_OBJECT_SPACE:
2333 					_writeRawConstant(i->physicalIndex, source->getLodCameraPositionObjectSpace(), i->elementCount);
2334 					break;
2335 
2336 				case ACT_CUSTOM:
2337 				case ACT_ANIMATION_PARAMETRIC:
2338 					source->getCurrentRenderable()->_updateCustomGpuParameter(*i, this);
2339 					break;
2340 				case ACT_LIGHT_CUSTOM:
2341 					source->updateLightCustomGpuParameter(*i, this);
2342 					break;
2343 				case ACT_LIGHT_COUNT:
2344 					_writeRawConstant(i->physicalIndex, source->getLightCount());
2345 					break;
2346 				case ACT_LIGHT_DIFFUSE_COLOUR:
2347 					_writeRawConstant(i->physicalIndex, source->getLightDiffuseColour(i->data), i->elementCount);
2348 					break;
2349 				case ACT_LIGHT_SPECULAR_COLOUR:
2350 					_writeRawConstant(i->physicalIndex, source->getLightSpecularColour(i->data), i->elementCount);
2351 					break;
2352 				case ACT_LIGHT_POSITION:
2353 					// Get as 4D vector, works for directional lights too
2354 					// Use element count in case uniform slot is smaller
2355 					_writeRawConstant(i->physicalIndex,
2356 						source->getLightAs4DVector(i->data), i->elementCount);
2357 					break;
2358 				case ACT_LIGHT_DIRECTION:
2359 					vec3 = source->getLightDirection(i->data);
2360 					// Set as 4D vector for compatibility
2361 					// Use element count in case uniform slot is smaller
2362 					_writeRawConstant(i->physicalIndex, Vector4(vec3.x, vec3.y, vec3.z, 1.0f), i->elementCount);
2363 					break;
2364 				case ACT_LIGHT_POSITION_VIEW_SPACE:
2365 					_writeRawConstant(i->physicalIndex,
2366 						source->getViewMatrix().transformAffine(source->getLightAs4DVector(i->data)), i->elementCount);
2367 					break;
2368 				case ACT_LIGHT_DIRECTION_VIEW_SPACE:
2369 					source->getInverseTransposeViewMatrix().extract3x3Matrix(m3);
2370 					// inverse transpose in case of scaling
2371 					vec3 = m3 * source->getLightDirection(i->data);
2372 					vec3.normalise();
2373 					// Set as 4D vector for compatibility
2374 					_writeRawConstant(i->physicalIndex, Vector4(vec3.x, vec3.y, vec3.z, 0.0f),i->elementCount);
2375 					break;
2376 				case ACT_SHADOW_EXTRUSION_DISTANCE:
2377 					// extrusion is in object-space, so we have to rescale by the inverse
2378 					// of the world scaling to deal with scaled objects
2379 					source->getWorldMatrix().extract3x3Matrix(m3);
2380 					_writeRawConstant(i->physicalIndex, source->getShadowExtrusionDistance() /
2381 						Math::Sqrt(std::max(std::max(m3.GetColumn(0).squaredLength(), m3.GetColumn(1).squaredLength()), m3.GetColumn(2).squaredLength())));
2382 					break;
2383 				case ACT_SHADOW_SCENE_DEPTH_RANGE:
2384 					_writeRawConstant(i->physicalIndex, source->getShadowSceneDepthRange(i->data));
2385 					break;
2386                 case ACT_SHADOW_SCENE_DEPTH_RANGE_ARRAY:
2387                     for (size_t l = 0; l < i->data; ++l)
2388                         _writeRawConstant(i->physicalIndex + l*i->elementCount, source->getShadowSceneDepthRange(i->data), i->elementCount);
2389                     break;
2390 				case ACT_SHADOW_COLOUR:
2391 					_writeRawConstant(i->physicalIndex, source->getShadowColour(), i->elementCount);
2392 					break;
2393 				case ACT_LIGHT_POWER_SCALE:
2394 					_writeRawConstant(i->physicalIndex, source->getLightPowerScale(i->data));
2395 					break;
2396 				case ACT_LIGHT_DIFFUSE_COLOUR_POWER_SCALED:
2397 					_writeRawConstant(i->physicalIndex, source->getLightDiffuseColourWithPower(i->data), i->elementCount);
2398 					break;
2399 				case ACT_LIGHT_SPECULAR_COLOUR_POWER_SCALED:
2400 					_writeRawConstant(i->physicalIndex, source->getLightSpecularColourWithPower(i->data), i->elementCount);
2401 					break;
2402 				case ACT_LIGHT_NUMBER:
2403 					_writeRawConstant(i->physicalIndex, source->getLightNumber(i->data));
2404 					break;
2405 				case ACT_LIGHT_CASTS_SHADOWS:
2406 					_writeRawConstant(i->physicalIndex, source->getLightCastsShadows(i->data));
2407 					break;
2408                 case ACT_LIGHT_CASTS_SHADOWS_ARRAY:
2409                     for (size_t l = 0; l < i->data; ++l)
2410                         _writeRawConstant(i->physicalIndex + l*i->elementCount, source->getLightCastsShadows(i->data), i->elementCount);
2411                     break;
2412 				case ACT_LIGHT_ATTENUATION:
2413 					_writeRawConstant(i->physicalIndex, source->getLightAttenuation(i->data), i->elementCount);
2414 					break;
2415 				case ACT_SPOTLIGHT_PARAMS:
2416 					_writeRawConstant(i->physicalIndex, source->getSpotlightParams(i->data), i->elementCount);
2417 					break;
2418 				case ACT_LIGHT_DIFFUSE_COLOUR_ARRAY:
2419 					for (size_t l = 0; l < i->data; ++l)
2420 						_writeRawConstant(i->physicalIndex + l*i->elementCount,
2421 						source->getLightDiffuseColour(l), i->elementCount);
2422 					break;
2423 
2424 				case ACT_LIGHT_SPECULAR_COLOUR_ARRAY:
2425 					for (size_t l = 0; l < i->data; ++l)
2426 						_writeRawConstant(i->physicalIndex + l*i->elementCount,
2427 						source->getLightSpecularColour(l), i->elementCount);
2428 					break;
2429 				case ACT_LIGHT_DIFFUSE_COLOUR_POWER_SCALED_ARRAY:
2430 					for (size_t l = 0; l < i->data; ++l)
2431 						_writeRawConstant(i->physicalIndex + l*i->elementCount,
2432 						source->getLightDiffuseColourWithPower(l), i->elementCount);
2433 					break;
2434 
2435 				case ACT_LIGHT_SPECULAR_COLOUR_POWER_SCALED_ARRAY:
2436 					for (size_t l = 0; l < i->data; ++l)
2437 						_writeRawConstant(i->physicalIndex + l*i->elementCount,
2438 						source->getLightSpecularColourWithPower(l), i->elementCount);
2439 					break;
2440 
2441 				case ACT_LIGHT_POSITION_ARRAY:
2442 					// Get as 4D vector, works for directional lights too
2443 					for (size_t l = 0; l < i->data; ++l)
2444 						_writeRawConstant(i->physicalIndex + l*i->elementCount,
2445 						source->getLightAs4DVector(l), i->elementCount);
2446 					break;
2447 
2448 				case ACT_LIGHT_DIRECTION_ARRAY:
2449 					for (size_t l = 0; l < i->data; ++l)
2450 					{
2451 						vec3 = source->getLightDirection(l);
2452 						// Set as 4D vector for compatibility
2453 						_writeRawConstant(i->physicalIndex + l*i->elementCount,
2454 							Vector4(vec3.x, vec3.y, vec3.z, 0.0f), i->elementCount);
2455 					}
2456 					break;
2457 
2458 				case ACT_LIGHT_POSITION_VIEW_SPACE_ARRAY:
2459 					for (size_t l = 0; l < i->data; ++l)
2460 						_writeRawConstant(i->physicalIndex + l*i->elementCount,
2461 						source->getViewMatrix().transformAffine(
2462 						source->getLightAs4DVector(l)),
2463 						i->elementCount);
2464 					break;
2465 
2466 				case ACT_LIGHT_DIRECTION_VIEW_SPACE_ARRAY:
2467 					source->getInverseTransposeViewMatrix().extract3x3Matrix(m3);
2468 					for (size_t l = 0; l < i->data; ++l)
2469 					{
2470 						vec3 = m3 * source->getLightDirection(l);
2471 						vec3.normalise();
2472 						// Set as 4D vector for compatibility
2473 						_writeRawConstant(i->physicalIndex + l*i->elementCount,
2474 							Vector4(vec3.x, vec3.y, vec3.z, 0.0f), i->elementCount);
2475 					}
2476 					break;
2477 
2478 				case ACT_LIGHT_POWER_SCALE_ARRAY:
2479 					for (size_t l = 0; l < i->data; ++l)
2480 						_writeRawConstant(i->physicalIndex + l*i->elementCount,
2481 						source->getLightPowerScale(l));
2482 					break;
2483 
2484 				case ACT_LIGHT_ATTENUATION_ARRAY:
2485 					for (size_t l = 0; l < i->data; ++l)
2486 					{
2487 						_writeRawConstant(i->physicalIndex + l*i->elementCount,
2488 							source->getLightAttenuation(l), i->elementCount);
2489 					}
2490 					break;
2491 				case ACT_SPOTLIGHT_PARAMS_ARRAY:
2492 					for (size_t l = 0 ; l < i->data; ++l)
2493 					{
2494 						_writeRawConstant(i->physicalIndex + l*i->elementCount, source->getSpotlightParams(l),
2495 							i->elementCount);
2496 					}
2497 					break;
2498 				case ACT_DERIVED_LIGHT_DIFFUSE_COLOUR:
2499 					_writeRawConstant(i->physicalIndex,
2500 						source->getLightDiffuseColourWithPower(i->data) * source->getSurfaceDiffuseColour(),
2501 						i->elementCount);
2502 					break;
2503 				case ACT_DERIVED_LIGHT_SPECULAR_COLOUR:
2504 					_writeRawConstant(i->physicalIndex,
2505 						source->getLightSpecularColourWithPower(i->data) * source->getSurfaceSpecularColour(),
2506 						i->elementCount);
2507 					break;
2508 				case ACT_DERIVED_LIGHT_DIFFUSE_COLOUR_ARRAY:
2509 					for (size_t l = 0; l < i->data; ++l)
2510 					{
2511 						_writeRawConstant(i->physicalIndex + l*i->elementCount,
2512 							source->getLightDiffuseColourWithPower(l) * source->getSurfaceDiffuseColour(),
2513 							i->elementCount);
2514 					}
2515 					break;
2516 				case ACT_DERIVED_LIGHT_SPECULAR_COLOUR_ARRAY:
2517 					for (size_t l = 0; l < i->data; ++l)
2518 					{
2519 						_writeRawConstant(i->physicalIndex + l*i->elementCount,
2520 							source->getLightSpecularColourWithPower(l) * source->getSurfaceSpecularColour(),
2521 							i->elementCount);
2522 					}
2523 					break;
2524 				case ACT_TEXTURE_VIEWPROJ_MATRIX:
2525 					// can also be updated in lights
2526 					_writeRawConstant(i->physicalIndex, source->getTextureViewProjMatrix(i->data),i->elementCount);
2527 					break;
2528 				case ACT_TEXTURE_VIEWPROJ_MATRIX_ARRAY:
2529 					for (size_t l = 0; l < i->data; ++l)
2530 					{
2531 						// can also be updated in lights
2532 						_writeRawConstant(i->physicalIndex + l*i->elementCount,
2533 							source->getTextureViewProjMatrix(l),i->elementCount);
2534 					}
2535 					break;
2536 				case ACT_SPOTLIGHT_VIEWPROJ_MATRIX:
2537 					_writeRawConstant(i->physicalIndex, source->getSpotlightViewProjMatrix(i->data),i->elementCount);
2538 					break;
2539 				case ACT_SPOTLIGHT_VIEWPROJ_MATRIX_ARRAY:
2540 					for (size_t l = 0; l < i->data; ++l)
2541 					{
2542 						// can also be updated in lights
2543 						_writeRawConstant(i->physicalIndex + l*i->elementCount,
2544 										  source->getSpotlightViewProjMatrix(l),i->elementCount);
2545 					}
2546 					break;
2547 
2548 				default:
2549 					break;
2550 				};
2551 			}
2552 		}
2553 
2554 	}
2555 	//---------------------------------------------------------------------------
setNamedConstant(const String & name,Real val)2556 	void GpuProgramParameters::setNamedConstant(const String& name, Real val)
2557 	{
2558 		// look up, and throw an exception if we're not ignoring missing
2559 		const GpuConstantDefinition* def =
2560 			_findNamedConstantDefinition(name, !mIgnoreMissingParams);
2561 		if (def)
2562 			_writeRawConstant(def->physicalIndex, val);
2563 	}
2564 	//---------------------------------------------------------------------------
setNamedConstant(const String & name,int val)2565 	void GpuProgramParameters::setNamedConstant(const String& name, int val)
2566 	{
2567 		// look up, and throw an exception if we're not ignoring missing
2568 		const GpuConstantDefinition* def =
2569 			_findNamedConstantDefinition(name, !mIgnoreMissingParams);
2570 		if (def)
2571 			_writeRawConstant(def->physicalIndex, val);
2572 	}
2573 	//---------------------------------------------------------------------------
setNamedConstant(const String & name,const Vector4 & vec)2574 	void GpuProgramParameters::setNamedConstant(const String& name, const Vector4& vec)
2575 	{
2576 		// look up, and throw an exception if we're not ignoring missing
2577 		const GpuConstantDefinition* def =
2578 			_findNamedConstantDefinition(name, !mIgnoreMissingParams);
2579 		if (def)
2580 			_writeRawConstant(def->physicalIndex, vec, def->elementSize);
2581 	}
2582 	//---------------------------------------------------------------------------
setNamedConstant(const String & name,const Vector3 & vec)2583 	void GpuProgramParameters::setNamedConstant(const String& name, const Vector3& vec)
2584 	{
2585 		// look up, and throw an exception if we're not ignoring missing
2586 		const GpuConstantDefinition* def =
2587 			_findNamedConstantDefinition(name, !mIgnoreMissingParams);
2588 		if (def)
2589 			_writeRawConstant(def->physicalIndex, vec);
2590 	}
2591 	//---------------------------------------------------------------------------
setNamedConstant(const String & name,const Vector2 & vec)2592 	void GpuProgramParameters::setNamedConstant(const String& name, const Vector2& vec)
2593 	{
2594 		// look up, and throw an exception if we're not ignoring missing
2595 		const GpuConstantDefinition* def =
2596         _findNamedConstantDefinition(name, !mIgnoreMissingParams);
2597 		if (def)
2598 			_writeRawConstant(def->physicalIndex, vec);
2599 	}
2600 	//---------------------------------------------------------------------------
setNamedConstant(const String & name,const Matrix4 & m)2601 	void GpuProgramParameters::setNamedConstant(const String& name, const Matrix4& m)
2602 	{
2603 		// look up, and throw an exception if we're not ignoring missing
2604 		const GpuConstantDefinition* def =
2605 			_findNamedConstantDefinition(name, !mIgnoreMissingParams);
2606 		if (def)
2607 			_writeRawConstant(def->physicalIndex, m, def->elementSize);
2608 	}
2609 	//---------------------------------------------------------------------------
setNamedConstant(const String & name,const Matrix4 * m,size_t numEntries)2610 	void GpuProgramParameters::setNamedConstant(const String& name, const Matrix4* m,
2611 		size_t numEntries)
2612 	{
2613 		// look up, and throw an exception if we're not ignoring missing
2614 		const GpuConstantDefinition* def =
2615 			_findNamedConstantDefinition(name, !mIgnoreMissingParams);
2616 		if (def)
2617 			_writeRawConstant(def->physicalIndex, m, numEntries);
2618 	}
2619 	//---------------------------------------------------------------------------
setNamedConstant(const String & name,const float * val,size_t count,size_t multiple)2620 	void GpuProgramParameters::setNamedConstant(const String& name,
2621 		const float *val, size_t count, size_t multiple)
2622 	{
2623 		size_t rawCount = count * multiple;
2624 		// look up, and throw an exception if we're not ignoring missing
2625 		const GpuConstantDefinition* def =
2626 			_findNamedConstantDefinition(name, !mIgnoreMissingParams);
2627 		if (def)
2628 			_writeRawConstants(def->physicalIndex, val, rawCount);
2629 	}
2630 	//---------------------------------------------------------------------------
setNamedConstant(const String & name,const double * val,size_t count,size_t multiple)2631 	void GpuProgramParameters::setNamedConstant(const String& name,
2632 		const double *val, size_t count, size_t multiple)
2633 	{
2634 		size_t rawCount = count * multiple;
2635 		// look up, and throw an exception if we're not ignoring missing
2636 		const GpuConstantDefinition* def =
2637 			_findNamedConstantDefinition(name, !mIgnoreMissingParams);
2638 		if (def)
2639 			_writeRawConstants(def->physicalIndex, val, rawCount);
2640 	}
2641 	//---------------------------------------------------------------------------
setNamedConstant(const String & name,const ColourValue & colour)2642 	void GpuProgramParameters::setNamedConstant(const String& name, const ColourValue& colour)
2643 	{
2644 		// look up, and throw an exception if we're not ignoring missing
2645 		const GpuConstantDefinition* def =
2646 			_findNamedConstantDefinition(name, !mIgnoreMissingParams);
2647 		if (def)
2648 			_writeRawConstant(def->physicalIndex, colour, def->elementSize);
2649 	}
2650 	//---------------------------------------------------------------------------
setNamedConstant(const String & name,const int * val,size_t count,size_t multiple)2651 	void GpuProgramParameters::setNamedConstant(const String& name,
2652 		const int *val, size_t count, size_t multiple)
2653 	{
2654 		size_t rawCount = count * multiple;
2655 		// look up, and throw an exception if we're not ignoring missing
2656 		const GpuConstantDefinition* def =
2657 			_findNamedConstantDefinition(name, !mIgnoreMissingParams);
2658 		if (def)
2659 			_writeRawConstants(def->physicalIndex, val, rawCount);
2660 	}
2661 	//---------------------------------------------------------------------
setNamedSubroutine(const String & subroutineSlot,const String & subroutine)2662 	void GpuProgramParameters::setNamedSubroutine(const String& subroutineSlot, const String& subroutine)
2663 	{
2664 		const GpuConstantDefinition* def =
2665 			_findNamedConstantDefinition(subroutineSlot, !mIgnoreMissingParams);
2666 		if (def)
2667 		{
2668 			setSubroutine(def->logicalIndex, subroutine);
2669 		}
2670 	}
2671 	//---------------------------------------------------------------------
setSubroutine(size_t index,const String & subroutine)2672 	void GpuProgramParameters::setSubroutine(size_t index, const String& subroutine)
2673 	{
2674 		mSubroutineMap.insert(std::make_pair(index, subroutine));
2675 	}
2676 	//---------------------------------------------------------------------------
setNamedAutoConstant(const String & name,AutoConstantType acType,size_t extraInfo)2677 	void GpuProgramParameters::setNamedAutoConstant(const String& name,
2678 		AutoConstantType acType, size_t extraInfo)
2679 	{
2680 		// look up, and throw an exception if we're not ignoring missing
2681 		const GpuConstantDefinition* def =
2682 			_findNamedConstantDefinition(name, !mIgnoreMissingParams);
2683 		if (def)
2684 		{
2685 			def->variability = deriveVariability(acType);
2686 			// make sure we also set variability on the logical index map
2687 			GpuLogicalIndexUse* indexUse = _getFloatConstantLogicalIndexUse(def->logicalIndex, def->elementSize * def->arraySize, def->variability);
2688 			if (indexUse)
2689 				indexUse->variability = def->variability;
2690 
2691 			_setRawAutoConstant(def->physicalIndex, acType, extraInfo, def->variability, def->elementSize);
2692 		}
2693 
2694 	}
2695 	//---------------------------------------------------------------------------
setNamedAutoConstantReal(const String & name,AutoConstantType acType,Real rData)2696 	void GpuProgramParameters::setNamedAutoConstantReal(const String& name,
2697 		AutoConstantType acType, Real rData)
2698 	{
2699 		// look up, and throw an exception if we're not ignoring missing
2700 		const GpuConstantDefinition* def =
2701 			_findNamedConstantDefinition(name, !mIgnoreMissingParams);
2702 		if (def)
2703 		{
2704 			def->variability = deriveVariability(acType);
2705 			// make sure we also set variability on the logical index map
2706 			GpuLogicalIndexUse* indexUse = _getFloatConstantLogicalIndexUse(def->logicalIndex, def->elementSize * def->arraySize, def->variability);
2707 			if (indexUse)
2708 				indexUse->variability = def->variability;
2709 			_setRawAutoConstantReal(def->physicalIndex, acType, rData, def->variability, def->elementSize);
2710 		}
2711 	}
2712 	//---------------------------------------------------------------------------
setNamedAutoConstant(const String & name,AutoConstantType acType,uint16 extraInfo1,uint16 extraInfo2)2713 	void GpuProgramParameters::setNamedAutoConstant(const String& name,
2714 		AutoConstantType acType, uint16 extraInfo1, uint16 extraInfo2)
2715 	{
2716 		size_t extraInfo = (size_t)extraInfo1 | ((size_t)extraInfo2) << 16;
2717 
2718 		// look up, and throw an exception if we're not ignoring missing
2719 		const GpuConstantDefinition* def =
2720 			_findNamedConstantDefinition(name, !mIgnoreMissingParams);
2721 		if (def)
2722 		{
2723 			def->variability = deriveVariability(acType);
2724 			// make sure we also set variability on the logical index map
2725 			GpuLogicalIndexUse* indexUse = _getFloatConstantLogicalIndexUse(def->logicalIndex, def->elementSize * def->arraySize, def->variability);
2726 			if (indexUse)
2727 				indexUse->variability = def->variability;
2728 
2729 			_setRawAutoConstant(def->physicalIndex, acType, extraInfo, def->variability, def->elementSize);
2730 		}
2731 
2732 	}
2733 	//---------------------------------------------------------------------------
setConstantFromTime(size_t index,Real factor)2734 	void GpuProgramParameters::setConstantFromTime(size_t index, Real factor)
2735 	{
2736 		setAutoConstantReal(index, ACT_TIME, factor);
2737 	}
2738 	//---------------------------------------------------------------------------
setNamedConstantFromTime(const String & name,Real factor)2739 	void GpuProgramParameters::setNamedConstantFromTime(const String& name, Real factor)
2740 	{
2741 		setNamedAutoConstantReal(name, ACT_TIME, factor);
2742 	}
2743 	//---------------------------------------------------------------------------
getAutoConstantEntry(const size_t index)2744 	GpuProgramParameters::AutoConstantEntry* GpuProgramParameters::getAutoConstantEntry(const size_t index)
2745 	{
2746 		if (index < mAutoConstants.size())
2747 		{
2748 			return &(mAutoConstants[index]);
2749 		}
2750 		else
2751 		{
2752 			return NULL;
2753 		}
2754 	}
2755 	//---------------------------------------------------------------------------
2756 	const GpuProgramParameters::AutoConstantEntry*
findFloatAutoConstantEntry(size_t logicalIndex)2757 		GpuProgramParameters::findFloatAutoConstantEntry(size_t logicalIndex)
2758 	{
2759 		if (mFloatLogicalToPhysical.isNull())
2760 			OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
2761 			"This is not a low-level parameter parameter object",
2762 			"GpuProgramParameters::findFloatAutoConstantEntry");
2763 
2764 		return _findRawAutoConstantEntryFloat(
2765 			_getFloatConstantPhysicalIndex(logicalIndex, 0, GPV_GLOBAL));
2766 
2767 	}
2768 	//---------------------------------------------------------------------------
2769 	const GpuProgramParameters::AutoConstantEntry*
findDoubleAutoConstantEntry(size_t logicalIndex)2770     GpuProgramParameters::findDoubleAutoConstantEntry(size_t logicalIndex)
2771 	{
2772 		if (mDoubleLogicalToPhysical.isNull())
2773 			OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
2774                         "This is not a low-level parameter parameter object",
2775                         "GpuProgramParameters::findDoubleAutoConstantEntry");
2776 
2777 		return _findRawAutoConstantEntryDouble(
2778               _getDoubleConstantPhysicalIndex(logicalIndex, 0, GPV_GLOBAL));
2779 	}
2780 	//---------------------------------------------------------------------------
2781 	const GpuProgramParameters::AutoConstantEntry*
findIntAutoConstantEntry(size_t logicalIndex)2782 		GpuProgramParameters::findIntAutoConstantEntry(size_t logicalIndex)
2783 	{
2784 		if (mIntLogicalToPhysical.isNull())
2785 			OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
2786 			"This is not a low-level parameter parameter object",
2787 			"GpuProgramParameters::findIntAutoConstantEntry");
2788 
2789 		return _findRawAutoConstantEntryInt(
2790 			_getIntConstantPhysicalIndex(logicalIndex, 0, GPV_GLOBAL));
2791 
2792 
2793 	}
2794 	//---------------------------------------------------------------------------
2795 	const GpuProgramParameters::AutoConstantEntry*
findAutoConstantEntry(const String & paramName)2796 		GpuProgramParameters::findAutoConstantEntry(const String& paramName)
2797 	{
2798 		if (mNamedConstants.isNull())
2799 			OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
2800 			"This params object is not based on a program with named parameters.",
2801 			"GpuProgramParameters::findAutoConstantEntry");
2802 
2803 		const GpuConstantDefinition& def = getConstantDefinition(paramName);
2804 		if (def.isFloat())
2805 		{
2806 			return _findRawAutoConstantEntryFloat(def.physicalIndex);
2807 		}
2808 		else
2809 		{
2810 			return _findRawAutoConstantEntryInt(def.physicalIndex);
2811 		}
2812 	}
2813 	//---------------------------------------------------------------------------
2814 	const GpuProgramParameters::AutoConstantEntry*
_findRawAutoConstantEntryFloat(size_t physicalIndex)2815 		GpuProgramParameters::_findRawAutoConstantEntryFloat(size_t physicalIndex)
2816 	{
2817 		for(AutoConstantList::iterator i = mAutoConstants.begin();
2818 			i != mAutoConstants.end(); ++i)
2819 		{
2820 			AutoConstantEntry& ac = *i;
2821 			// should check that auto is float and not int so that physicalIndex
2822 			// doesn't have any ambiguity
2823 			// However, all autos are float I think so no need
2824 			if (ac.physicalIndex == physicalIndex)
2825 				return &ac;
2826 		}
2827 
2828 		return 0;
2829 
2830 	}
2831 	//---------------------------------------------------------------------------
2832 	const GpuProgramParameters::AutoConstantEntry*
_findRawAutoConstantEntryDouble(size_t physicalIndex)2833     GpuProgramParameters::_findRawAutoConstantEntryDouble(size_t physicalIndex)
2834 	{
2835 		for(AutoConstantList::iterator i = mAutoConstants.begin();
2836 			i != mAutoConstants.end(); ++i)
2837 		{
2838 			AutoConstantEntry& ac = *i;
2839 			// should check that auto is double and not int or float so that physicalIndex
2840 			// doesn't have any ambiguity
2841 			// However, all autos are float I think so no need
2842 			if (ac.physicalIndex == physicalIndex)
2843 				return &ac;
2844 		}
2845 
2846 		return 0;
2847 
2848 	}
2849 	//---------------------------------------------------------------------------
2850 	const GpuProgramParameters::AutoConstantEntry*
_findRawAutoConstantEntryInt(size_t physicalIndex)2851 		GpuProgramParameters::_findRawAutoConstantEntryInt(size_t physicalIndex)
2852 	{
2853 		// No autos are float?
2854 		return 0;
2855 	}
2856 	//---------------------------------------------------------------------------
copyConstantsFrom(const GpuProgramParameters & source)2857 	void GpuProgramParameters::copyConstantsFrom(const GpuProgramParameters& source)
2858 	{
2859 		// Pull buffers & auto constant list over directly
2860 		mFloatConstants = source.getFloatConstantList();
2861 		mIntConstants = source.getIntConstantList();
2862 		mAutoConstants = source.getAutoConstantList();
2863 		mCombinedVariability = source.mCombinedVariability;
2864 		copySharedParamSetUsage(source.mSharedParamSets);
2865 	}
2866 	//---------------------------------------------------------------------
copyMatchingNamedConstantsFrom(const GpuProgramParameters & source)2867 	void GpuProgramParameters::copyMatchingNamedConstantsFrom(const GpuProgramParameters& source)
2868 	{
2869 		if (!mNamedConstants.isNull() && !source.mNamedConstants.isNull())
2870 		{
2871 			std::map<size_t, String> srcToDestNamedMap;
2872 			for (GpuConstantDefinitionMap::const_iterator i = source.mNamedConstants->map.begin();
2873 				i != source.mNamedConstants->map.end(); ++i)
2874 			{
2875 				const String& paramName = i->first;
2876 				const GpuConstantDefinition& olddef = i->second;
2877 				const GpuConstantDefinition* newdef = _findNamedConstantDefinition(paramName, false);
2878 				if (newdef)
2879 				{
2880 					// Copy data across, based on smallest common definition size
2881 					size_t srcsz = olddef.elementSize * olddef.arraySize;
2882 					size_t destsz = newdef->elementSize * newdef->arraySize;
2883 					size_t sz = std::min(srcsz, destsz);
2884 					if (newdef->isFloat())
2885 					{
2886 
2887 						memcpy(getFloatPointer(newdef->physicalIndex),
2888 							source.getFloatPointer(olddef.physicalIndex),
2889 							sz * sizeof(float));
2890 					}
2891 					else if (newdef->isDouble())
2892 					{
2893 
2894 						memcpy(getDoublePointer(newdef->physicalIndex),
2895                                source.getDoublePointer(olddef.physicalIndex),
2896                                sz * sizeof(double));
2897 					}
2898 					else
2899 					{
2900 						memcpy(getIntPointer(newdef->physicalIndex),
2901 							source.getIntPointer(olddef.physicalIndex),
2902 							sz * sizeof(int));
2903 					}
2904 					// we'll use this map to resolve autos later
2905 					// ignore the [0] aliases
2906 					if (!StringUtil::endsWith(paramName, "[0]"))
2907 						srcToDestNamedMap[olddef.physicalIndex] = paramName;
2908 				}
2909 			}
2910 
2911 			for (AutoConstantList::const_iterator i = source.mAutoConstants.begin();
2912 				i != source.mAutoConstants.end(); ++i)
2913 			{
2914 				const GpuProgramParameters::AutoConstantEntry& autoEntry = *i;
2915 				// find dest physical index
2916 				std::map<size_t, String>::iterator mi = srcToDestNamedMap.find(autoEntry.physicalIndex);
2917 				if (mi != srcToDestNamedMap.end())
2918 				{
2919 					if (autoEntry.fData)
2920 					{
2921 						setNamedAutoConstantReal(mi->second, autoEntry.paramType, autoEntry.fData);
2922 					}
2923 					else
2924 					{
2925 						setNamedAutoConstant(mi->second, autoEntry.paramType, autoEntry.data);
2926 					}
2927 				}
2928 
2929 			}
2930 
2931 			// Copy shared param sets
2932 			for (GpuSharedParamUsageList::const_iterator i = source.mSharedParamSets.begin();
2933 				i != source.mSharedParamSets.end(); ++i)
2934 			{
2935 				const GpuSharedParametersUsage& usage = *i;
2936 				if (!isUsingSharedParameters(usage.getName()))
2937 				{
2938 					addSharedParameters(usage.getSharedParams());
2939 				}
2940 			}
2941 		}
2942 	}
2943 	//-----------------------------------------------------------------------
2944 	const GpuProgramParameters::AutoConstantDefinition*
getAutoConstantDefinition(const String & name)2945 		GpuProgramParameters::getAutoConstantDefinition(const String& name)
2946 	{
2947 		// find a constant definition that matches name by iterating through the
2948 		// constant definition array
2949 		bool nameFound = false;
2950 		size_t i = 0;
2951 		const size_t numDefs = getNumAutoConstantDefinitions();
2952 		while (!nameFound && (i < numDefs))
2953 		{
2954 			if (name == AutoConstantDictionary[i].name)
2955 				nameFound = true;
2956 			else
2957 				++i;
2958 		}
2959 
2960 		if (nameFound)
2961 			return &AutoConstantDictionary[i];
2962 		else
2963 			return 0;
2964 	}
2965 
2966 	//-----------------------------------------------------------------------
2967 	const GpuProgramParameters::AutoConstantDefinition*
getAutoConstantDefinition(const size_t idx)2968 		GpuProgramParameters::getAutoConstantDefinition(const size_t idx)
2969 	{
2970 
2971 		if (idx < getNumAutoConstantDefinitions())
2972 		{
2973 			// verify index is equal to acType
2974 			// if they are not equal then the dictionary was not setup properly
2975 			assert(idx == static_cast<size_t>(AutoConstantDictionary[idx].acType));
2976 			return &AutoConstantDictionary[idx];
2977 		}
2978 		else
2979 			return 0;
2980 	}
2981 	//-----------------------------------------------------------------------
getNumAutoConstantDefinitions(void)2982 	size_t GpuProgramParameters::getNumAutoConstantDefinitions(void)
2983 	{
2984 		return sizeof(AutoConstantDictionary)/sizeof(AutoConstantDefinition);
2985 	}
2986 
2987 	//-----------------------------------------------------------------------
incPassIterationNumber(void)2988 	void GpuProgramParameters::incPassIterationNumber(void)
2989 	{
2990 		if (mActivePassIterationIndex != std::numeric_limits<size_t>::max())
2991 		{
2992 			// This is a physical index
2993 			++mFloatConstants[mActivePassIterationIndex];
2994 		}
2995 	}
2996 	//---------------------------------------------------------------------
addSharedParameters(GpuSharedParametersPtr sharedParams)2997 	void GpuProgramParameters::addSharedParameters(GpuSharedParametersPtr sharedParams)
2998 	{
2999 		if (!isUsingSharedParameters(sharedParams->getName()))
3000 		{
3001 			mSharedParamSets.push_back(GpuSharedParametersUsage(sharedParams, this));
3002 		}
3003 	}
3004 	//---------------------------------------------------------------------
addSharedParameters(const String & sharedParamsName)3005 	void GpuProgramParameters::addSharedParameters(const String& sharedParamsName)
3006 	{
3007 		addSharedParameters(GpuProgramManager::getSingleton().getSharedParameters(sharedParamsName));
3008 	}
3009 	//---------------------------------------------------------------------
isUsingSharedParameters(const String & sharedParamsName) const3010 	bool GpuProgramParameters::isUsingSharedParameters(const String& sharedParamsName) const
3011 	{
3012 		for (GpuSharedParamUsageList::const_iterator i = mSharedParamSets.begin();
3013 			i != mSharedParamSets.end(); ++i)
3014 		{
3015 			if (i->getName() == sharedParamsName)
3016 				return true;
3017 		}
3018 		return false;
3019 	}
3020 	//---------------------------------------------------------------------
removeSharedParameters(const String & sharedParamsName)3021 	void GpuProgramParameters::removeSharedParameters(const String& sharedParamsName)
3022 	{
3023 		for (GpuSharedParamUsageList::iterator i = mSharedParamSets.begin();
3024 			i != mSharedParamSets.end(); ++i)
3025 		{
3026 			if (i->getName() == sharedParamsName)
3027 			{
3028 				mSharedParamSets.erase(i);
3029 				break;
3030 			}
3031 		}
3032 	}
3033 	//---------------------------------------------------------------------
removeAllSharedParameters()3034 	void GpuProgramParameters::removeAllSharedParameters()
3035 	{
3036 		mSharedParamSets.clear();
3037 	}
3038 	//---------------------------------------------------------------------
3039 	const GpuProgramParameters::GpuSharedParamUsageList&
getSharedParameters() const3040 	GpuProgramParameters::getSharedParameters() const
3041 	{
3042 		return mSharedParamSets;
3043 	}
3044 	//---------------------------------------------------------------------
_copySharedParams()3045 	void GpuProgramParameters::_copySharedParams()
3046 	{
3047 		for (GpuSharedParamUsageList::iterator i = mSharedParamSets.begin();
3048 			i != mSharedParamSets.end(); ++i )
3049 		{
3050 			i->_copySharedParamsToTargetParams();
3051 		}
3052 
3053 	}
3054 
3055 
3056 
3057 
3058 }
3059