1 /* 2 ----------------------------------------------------------------------------- 3 This source file is part of OGRE 4 (Object-oriented Graphics Rendering Engine) 5 For the latest info, see http://www.ogre3d.org/ 6 7 Copyright (c) 2000-2014 Torus Knot Software Ltd 8 9 Permission is hereby granted, free of charge, to any person obtaining a copy 10 of this software and associated documentation files (the "Software"), to deal 11 in the Software without restriction, including without limitation the rights 12 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 copies of the Software, and to permit persons to whom the Software is 14 furnished to do so, subject to the following conditions: 15 16 The above copyright notice and this permission notice shall be included in 17 all copies or substantial portions of the Software. 18 19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 THE SOFTWARE. 26 ----------------------------------------------------------------------------- 27 */ 28 29 #include "OgreGLSLProgramManager.h" 30 #include "OgreLogManager.h" 31 #include "OgreStringConverter.h" 32 #include "OgreGLSLShader.h" 33 #include "OgreGpuProgramManager.h" 34 #include "OgreGL3PlusHardwareBufferManager.h" 35 #include "OgreGL3PlusRenderSystem.h" 36 #include "OgreRoot.h" 37 38 #include "OgreGLSLMonolithicProgram.h" 39 #include "OgreGLSLSeparableProgram.h" 40 41 namespace Ogre { 42 43 template<> GLSLProgramManager* Singleton<GLSLProgramManager>::msSingleton = 0; 44 45 getSingletonPtr(void)46 GLSLProgramManager* GLSLProgramManager::getSingletonPtr(void) 47 { 48 return msSingleton; 49 } 50 51 getSingleton(void)52 GLSLProgramManager& GLSLProgramManager::getSingleton(void) 53 { 54 assert(msSingleton); 55 return (*msSingleton); 56 } 57 GLSLProgramManager(GL3PlusRenderSystem * renderSystem)58 GLSLProgramManager::GLSLProgramManager(GL3PlusRenderSystem* renderSystem) : 59 mActiveVertexShader(NULL), 60 mActiveHullShader(NULL), 61 mActiveDomainShader(NULL), 62 mActiveGeometryShader(NULL), 63 mActiveFragmentShader(NULL), 64 mActiveComputeShader(NULL), 65 mActiveProgram(NULL), 66 mRenderSystem(renderSystem) 67 { 68 // Fill in the relationship between type names and enums 69 mTypeEnumMap.insert(StringToEnumMap::value_type("float", GL_FLOAT)); 70 mTypeEnumMap.insert(StringToEnumMap::value_type("vec2", GL_FLOAT_VEC2)); 71 mTypeEnumMap.insert(StringToEnumMap::value_type("vec3", GL_FLOAT_VEC3)); 72 mTypeEnumMap.insert(StringToEnumMap::value_type("vec4", GL_FLOAT_VEC4)); 73 mTypeEnumMap.insert(StringToEnumMap::value_type("sampler1D", GL_SAMPLER_1D)); 74 mTypeEnumMap.insert(StringToEnumMap::value_type("sampler2D", GL_SAMPLER_2D)); 75 mTypeEnumMap.insert(StringToEnumMap::value_type("sampler3D", GL_SAMPLER_3D)); 76 mTypeEnumMap.insert(StringToEnumMap::value_type("samplerCube", GL_SAMPLER_CUBE)); 77 mTypeEnumMap.insert(StringToEnumMap::value_type("sampler1DShadow", GL_SAMPLER_1D_SHADOW)); 78 mTypeEnumMap.insert(StringToEnumMap::value_type("sampler2DShadow", GL_SAMPLER_2D_SHADOW)); 79 mTypeEnumMap.insert(StringToEnumMap::value_type("int", GL_INT)); 80 mTypeEnumMap.insert(StringToEnumMap::value_type("ivec2", GL_INT_VEC2)); 81 mTypeEnumMap.insert(StringToEnumMap::value_type("ivec3", GL_INT_VEC3)); 82 mTypeEnumMap.insert(StringToEnumMap::value_type("ivec4", GL_INT_VEC4)); 83 mTypeEnumMap.insert(StringToEnumMap::value_type("bool", GL_BOOL)); 84 mTypeEnumMap.insert(StringToEnumMap::value_type("bvec2", GL_BOOL_VEC2)); 85 mTypeEnumMap.insert(StringToEnumMap::value_type("bvec3", GL_BOOL_VEC3)); 86 mTypeEnumMap.insert(StringToEnumMap::value_type("bvec4", GL_BOOL_VEC4)); 87 mTypeEnumMap.insert(StringToEnumMap::value_type("mat2", GL_FLOAT_MAT2)); 88 mTypeEnumMap.insert(StringToEnumMap::value_type("mat3", GL_FLOAT_MAT3)); 89 mTypeEnumMap.insert(StringToEnumMap::value_type("mat4", GL_FLOAT_MAT4)); 90 91 // GL 2.1 92 mTypeEnumMap.insert(StringToEnumMap::value_type("mat2x2", GL_FLOAT_MAT2)); 93 mTypeEnumMap.insert(StringToEnumMap::value_type("mat3x3", GL_FLOAT_MAT3)); 94 mTypeEnumMap.insert(StringToEnumMap::value_type("mat4x4", GL_FLOAT_MAT4)); 95 mTypeEnumMap.insert(StringToEnumMap::value_type("mat2x3", GL_FLOAT_MAT2x3)); 96 mTypeEnumMap.insert(StringToEnumMap::value_type("mat3x2", GL_FLOAT_MAT3x2)); 97 mTypeEnumMap.insert(StringToEnumMap::value_type("mat3x4", GL_FLOAT_MAT3x4)); 98 mTypeEnumMap.insert(StringToEnumMap::value_type("mat4x3", GL_FLOAT_MAT4x3)); 99 mTypeEnumMap.insert(StringToEnumMap::value_type("mat2x4", GL_FLOAT_MAT2x4)); 100 mTypeEnumMap.insert(StringToEnumMap::value_type("mat4x2", GL_FLOAT_MAT4x2)); 101 102 // GL 3.0 103 mTypeEnumMap.insert(StringToEnumMap::value_type("uint", GL_UNSIGNED_INT)); 104 mTypeEnumMap.insert(StringToEnumMap::value_type("uvec2", GL_UNSIGNED_INT_VEC2)); 105 mTypeEnumMap.insert(StringToEnumMap::value_type("uvec3", GL_UNSIGNED_INT_VEC3)); 106 mTypeEnumMap.insert(StringToEnumMap::value_type("uvec4", GL_UNSIGNED_INT_VEC4)); 107 mTypeEnumMap.insert(StringToEnumMap::value_type("samplerCubeShadow", GL_SAMPLER_CUBE_SHADOW)); 108 mTypeEnumMap.insert(StringToEnumMap::value_type("sampler1DArray", GL_SAMPLER_1D_ARRAY)); 109 mTypeEnumMap.insert(StringToEnumMap::value_type("sampler2DArray", GL_SAMPLER_2D_ARRAY)); 110 mTypeEnumMap.insert(StringToEnumMap::value_type("sampler1DArrayShadow", GL_SAMPLER_1D_ARRAY_SHADOW)); 111 mTypeEnumMap.insert(StringToEnumMap::value_type("sampler2DArrayShadow", GL_SAMPLER_2D_ARRAY_SHADOW)); 112 mTypeEnumMap.insert(StringToEnumMap::value_type("isampler1D", GL_INT_SAMPLER_1D)); 113 mTypeEnumMap.insert(StringToEnumMap::value_type("isampler2D", GL_INT_SAMPLER_2D)); 114 mTypeEnumMap.insert(StringToEnumMap::value_type("isampler3D", GL_INT_SAMPLER_3D)); 115 mTypeEnumMap.insert(StringToEnumMap::value_type("isamplerCube", GL_INT_SAMPLER_CUBE)); 116 mTypeEnumMap.insert(StringToEnumMap::value_type("isampler1DArray", GL_INT_SAMPLER_1D_ARRAY)); 117 mTypeEnumMap.insert(StringToEnumMap::value_type("isampler2DArray", GL_INT_SAMPLER_2D_ARRAY)); 118 mTypeEnumMap.insert(StringToEnumMap::value_type("usampler1D", GL_UNSIGNED_INT_SAMPLER_1D)); 119 mTypeEnumMap.insert(StringToEnumMap::value_type("usampler2D", GL_UNSIGNED_INT_SAMPLER_2D)); 120 mTypeEnumMap.insert(StringToEnumMap::value_type("usampler3D", GL_UNSIGNED_INT_SAMPLER_3D)); 121 mTypeEnumMap.insert(StringToEnumMap::value_type("usamplerCube", GL_UNSIGNED_INT_SAMPLER_CUBE)); 122 mTypeEnumMap.insert(StringToEnumMap::value_type("usampler1DArray", GL_UNSIGNED_INT_SAMPLER_1D_ARRAY)); 123 mTypeEnumMap.insert(StringToEnumMap::value_type("usampler2DArray", GL_UNSIGNED_INT_SAMPLER_2D_ARRAY)); 124 125 // GL 3.1 126 mTypeEnumMap.insert(StringToEnumMap::value_type("sampler2DRect", GL_SAMPLER_2D_RECT)); 127 mTypeEnumMap.insert(StringToEnumMap::value_type("sampler2DRectShadow", GL_SAMPLER_2D_RECT_SHADOW)); 128 mTypeEnumMap.insert(StringToEnumMap::value_type("isampler2DRect", GL_INT_SAMPLER_2D_RECT)); 129 mTypeEnumMap.insert(StringToEnumMap::value_type("usampler2DRect", GL_UNSIGNED_INT_SAMPLER_2D_RECT)); 130 mTypeEnumMap.insert(StringToEnumMap::value_type("samplerBuffer", GL_SAMPLER_BUFFER)); 131 mTypeEnumMap.insert(StringToEnumMap::value_type("isamplerBuffer", GL_INT_SAMPLER_BUFFER)); 132 mTypeEnumMap.insert(StringToEnumMap::value_type("usamplerBuffer", GL_UNSIGNED_INT_SAMPLER_BUFFER)); 133 134 // GL 3.2 135 mTypeEnumMap.insert(StringToEnumMap::value_type("sampler2DMS", GL_SAMPLER_2D_MULTISAMPLE)); 136 mTypeEnumMap.insert(StringToEnumMap::value_type("isampler2DMS", GL_INT_SAMPLER_2D_MULTISAMPLE)); 137 mTypeEnumMap.insert(StringToEnumMap::value_type("usampler2DMS", GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE)); 138 mTypeEnumMap.insert(StringToEnumMap::value_type("sampler2DMSArray", GL_SAMPLER_2D_MULTISAMPLE_ARRAY)); 139 mTypeEnumMap.insert(StringToEnumMap::value_type("isampler2DMSArray", GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY)); 140 mTypeEnumMap.insert(StringToEnumMap::value_type("usampler2DMSArray", GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY)); 141 142 // GL 4.0 143 mTypeEnumMap.insert(StringToEnumMap::value_type("double", GL_DOUBLE)); 144 mTypeEnumMap.insert(StringToEnumMap::value_type("dmat2", GL_DOUBLE_MAT2)); 145 mTypeEnumMap.insert(StringToEnumMap::value_type("dmat3", GL_DOUBLE_MAT3)); 146 mTypeEnumMap.insert(StringToEnumMap::value_type("dmat4", GL_DOUBLE_MAT4)); 147 mTypeEnumMap.insert(StringToEnumMap::value_type("dmat2x2", GL_DOUBLE_MAT2)); 148 mTypeEnumMap.insert(StringToEnumMap::value_type("dmat3x3", GL_DOUBLE_MAT3)); 149 mTypeEnumMap.insert(StringToEnumMap::value_type("dmat4x4", GL_DOUBLE_MAT4)); 150 mTypeEnumMap.insert(StringToEnumMap::value_type("dmat2x3", GL_DOUBLE_MAT2x3)); 151 mTypeEnumMap.insert(StringToEnumMap::value_type("dmat3x2", GL_DOUBLE_MAT3x2)); 152 mTypeEnumMap.insert(StringToEnumMap::value_type("dmat3x4", GL_DOUBLE_MAT3x4)); 153 mTypeEnumMap.insert(StringToEnumMap::value_type("dmat4x3", GL_DOUBLE_MAT4x3)); 154 mTypeEnumMap.insert(StringToEnumMap::value_type("dmat2x4", GL_DOUBLE_MAT2x4)); 155 mTypeEnumMap.insert(StringToEnumMap::value_type("dmat4x2", GL_DOUBLE_MAT4x2)); 156 mTypeEnumMap.insert(StringToEnumMap::value_type("dvec2", GL_DOUBLE_VEC2)); 157 mTypeEnumMap.insert(StringToEnumMap::value_type("dvec3", GL_DOUBLE_VEC3)); 158 mTypeEnumMap.insert(StringToEnumMap::value_type("dvec4", GL_DOUBLE_VEC4)); 159 mTypeEnumMap.insert(StringToEnumMap::value_type("samplerCubeArray", GL_SAMPLER_CUBE_MAP_ARRAY)); 160 mTypeEnumMap.insert(StringToEnumMap::value_type("samplerCubeArrayShadow", GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW)); 161 mTypeEnumMap.insert(StringToEnumMap::value_type("isamplerCubeArray", GL_INT_SAMPLER_CUBE_MAP_ARRAY)); 162 mTypeEnumMap.insert(StringToEnumMap::value_type("usamplerCubeArray", GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY)); 163 164 mTypeEnumMap.insert(StringToEnumMap::value_type("image1D", GL_IMAGE_1D)); 165 mTypeEnumMap.insert(StringToEnumMap::value_type("iimage1D", GL_INT_IMAGE_1D)); 166 mTypeEnumMap.insert(StringToEnumMap::value_type("uimage1D", GL_UNSIGNED_INT_IMAGE_1D)); 167 mTypeEnumMap.insert(StringToEnumMap::value_type("image2D", GL_IMAGE_2D)); 168 mTypeEnumMap.insert(StringToEnumMap::value_type("iimage2D", GL_INT_IMAGE_2D)); 169 mTypeEnumMap.insert(StringToEnumMap::value_type("uimage2D", GL_UNSIGNED_INT_IMAGE_2D)); 170 mTypeEnumMap.insert(StringToEnumMap::value_type("image3D", GL_IMAGE_3D)); 171 mTypeEnumMap.insert(StringToEnumMap::value_type("iimage3D", GL_INT_IMAGE_3D)); 172 mTypeEnumMap.insert(StringToEnumMap::value_type("uimage3D", GL_UNSIGNED_INT_IMAGE_3D)); 173 mTypeEnumMap.insert(StringToEnumMap::value_type("image2DRect", GL_IMAGE_2D_RECT)); 174 mTypeEnumMap.insert(StringToEnumMap::value_type("iimage2DRect", GL_INT_IMAGE_2D_RECT)); 175 mTypeEnumMap.insert(StringToEnumMap::value_type("uimage2DRect", GL_UNSIGNED_INT_IMAGE_2D_RECT)); 176 mTypeEnumMap.insert(StringToEnumMap::value_type("imageCube", GL_IMAGE_CUBE)); 177 mTypeEnumMap.insert(StringToEnumMap::value_type("iimageCube", GL_INT_IMAGE_CUBE)); 178 mTypeEnumMap.insert(StringToEnumMap::value_type("uimageCube", GL_UNSIGNED_INT_IMAGE_CUBE)); 179 mTypeEnumMap.insert(StringToEnumMap::value_type("imageBuffer", GL_IMAGE_BUFFER)); 180 mTypeEnumMap.insert(StringToEnumMap::value_type("iimageBuffer", GL_INT_IMAGE_BUFFER)); 181 mTypeEnumMap.insert(StringToEnumMap::value_type("uimageBuffer", GL_UNSIGNED_INT_IMAGE_BUFFER)); 182 mTypeEnumMap.insert(StringToEnumMap::value_type("image1DArray", GL_IMAGE_1D_ARRAY)); 183 mTypeEnumMap.insert(StringToEnumMap::value_type("iimage1DArray", GL_INT_IMAGE_1D_ARRAY)); 184 mTypeEnumMap.insert(StringToEnumMap::value_type("uimage1DArray", GL_UNSIGNED_INT_IMAGE_1D_ARRAY)); 185 mTypeEnumMap.insert(StringToEnumMap::value_type("image2DArray", GL_IMAGE_2D_ARRAY)); 186 mTypeEnumMap.insert(StringToEnumMap::value_type("iimage2DArray", GL_INT_IMAGE_2D_ARRAY)); 187 mTypeEnumMap.insert(StringToEnumMap::value_type("uimage2DArray", GL_UNSIGNED_INT_IMAGE_2D_ARRAY)); 188 mTypeEnumMap.insert(StringToEnumMap::value_type("imageCubeArray", GL_IMAGE_CUBE_MAP_ARRAY)); 189 mTypeEnumMap.insert(StringToEnumMap::value_type("iimageCubeArray", GL_INT_IMAGE_CUBE_MAP_ARRAY)); 190 mTypeEnumMap.insert(StringToEnumMap::value_type("uimageCubeArray", GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY)); 191 mTypeEnumMap.insert(StringToEnumMap::value_type("image2DMS", GL_IMAGE_2D_MULTISAMPLE)); 192 mTypeEnumMap.insert(StringToEnumMap::value_type("iimage2DMS", GL_INT_IMAGE_2D_MULTISAMPLE)); 193 mTypeEnumMap.insert(StringToEnumMap::value_type("uimage2DMS", GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE)); 194 mTypeEnumMap.insert(StringToEnumMap::value_type("image2DMSArray", GL_IMAGE_2D_MULTISAMPLE_ARRAY)); 195 mTypeEnumMap.insert(StringToEnumMap::value_type("iimage2DMSArray", GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY)); 196 mTypeEnumMap.insert(StringToEnumMap::value_type("uimage2DMSArray", GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY)); 197 198 // GL 4.2 199 mTypeEnumMap.insert(StringToEnumMap::value_type("atomic_uint", GL_UNSIGNED_INT_ATOMIC_COUNTER)); 200 } 201 ~GLSLProgramManager(void)202 GLSLProgramManager::~GLSLProgramManager(void) {} 203 getStateCacheManager()204 GL3PlusStateCacheManager* GLSLProgramManager::getStateCacheManager() 205 { 206 return mRenderSystem->_getStateCacheManager(); 207 } 208 getActiveProgram(void)209 GLSLProgram* GLSLProgramManager::getActiveProgram(void) 210 { 211 // If there is an active link program then return it. 212 if (mActiveProgram) 213 return mActiveProgram; 214 215 // No active link program so find one or make a new one. 216 // Is there an active key? 217 uint32 activeKey = 0; 218 if (mActiveVertexShader) 219 { 220 activeKey = HashCombine(activeKey, mActiveVertexShader->getShaderID()); 221 } 222 if (mActiveDomainShader) 223 { 224 activeKey = HashCombine(activeKey, mActiveDomainShader->getShaderID()); 225 } 226 if (mActiveHullShader) 227 { 228 activeKey = HashCombine(activeKey, mActiveHullShader->getShaderID()); 229 } 230 if (mActiveGeometryShader) 231 { 232 activeKey = HashCombine(activeKey, mActiveGeometryShader->getShaderID()); 233 } 234 if (mActiveFragmentShader) 235 { 236 activeKey = HashCombine(activeKey, mActiveFragmentShader->getShaderID()); 237 } 238 if (mActiveComputeShader) 239 { 240 activeKey = HashCombine(activeKey, mActiveComputeShader->getShaderID()); 241 } 242 243 // Only return a link program object if a program exists. 244 if (activeKey > 0) 245 { 246 // Find the key in the hash map. 247 ProgramIterator programFound = mPrograms.find(activeKey); 248 // Program object not found for key so need to create it. 249 if (programFound == mPrograms.end()) 250 { 251 if (mRenderSystem->getCapabilities()->hasCapability(RSC_SEPARATE_SHADER_OBJECTS)) 252 { 253 mActiveProgram = new GLSLSeparableProgram( 254 mActiveVertexShader, mActiveHullShader, mActiveDomainShader, 255 mActiveGeometryShader, mActiveFragmentShader, mActiveComputeShader); 256 } 257 else 258 { 259 mActiveProgram = new GLSLMonolithicProgram( 260 mActiveVertexShader, mActiveHullShader, mActiveDomainShader, 261 mActiveGeometryShader, mActiveFragmentShader, mActiveComputeShader); 262 } 263 264 mPrograms[activeKey] = mActiveProgram; 265 } 266 else 267 { 268 // Found a link program in map container so make it active. 269 mActiveProgram = static_cast<GLSLProgram*>(programFound->second); 270 } 271 } 272 273 // Make the program object active. 274 if (mActiveProgram) 275 mActiveProgram->activate(); 276 277 return mActiveProgram; 278 } 279 setActiveFragmentShader(GLSLShader * fragmentShader)280 void GLSLProgramManager::setActiveFragmentShader(GLSLShader* fragmentShader) 281 { 282 if (fragmentShader != mActiveFragmentShader) 283 { 284 mActiveFragmentShader = fragmentShader; 285 // ActiveMonolithicProgram is no longer valid 286 mActiveProgram = NULL; 287 } 288 } 289 290 setActiveVertexShader(GLSLShader * vertexShader)291 void GLSLProgramManager::setActiveVertexShader(GLSLShader* vertexShader) 292 { 293 if (vertexShader != mActiveVertexShader) 294 { 295 mActiveVertexShader = vertexShader; 296 // ActiveMonolithicProgram is no longer valid 297 mActiveProgram = NULL; 298 } 299 } 300 301 setActiveGeometryShader(GLSLShader * geometryShader)302 void GLSLProgramManager::setActiveGeometryShader(GLSLShader* geometryShader) 303 { 304 if (geometryShader != mActiveGeometryShader) 305 { 306 mActiveGeometryShader = geometryShader; 307 // ActiveMonolithicProgram is no longer valid 308 mActiveProgram = NULL; 309 } 310 } 311 312 setActiveHullShader(GLSLShader * hullShader)313 void GLSLProgramManager::setActiveHullShader(GLSLShader* hullShader) 314 { 315 if (hullShader != mActiveHullShader) 316 { 317 mActiveHullShader = hullShader; 318 // ActiveMonolithicProgram is no longer valid 319 mActiveProgram = NULL; 320 } 321 } 322 323 setActiveDomainShader(GLSLShader * domainShader)324 void GLSLProgramManager::setActiveDomainShader(GLSLShader* domainShader) 325 { 326 if (domainShader != mActiveDomainShader) 327 { 328 mActiveDomainShader = domainShader; 329 // ActiveMonolithicProgram is no longer valid 330 mActiveProgram = NULL; 331 } 332 } 333 334 setActiveComputeShader(GLSLShader * computeShader)335 void GLSLProgramManager::setActiveComputeShader(GLSLShader* computeShader) 336 { 337 if (computeShader != mActiveComputeShader) 338 { 339 mActiveComputeShader = computeShader; 340 // ActiveMonolithicProgram is no longer valid 341 mActiveProgram = NULL; 342 } 343 } 344 convertGLUniformtoOgreType(GLenum gltype,GpuConstantDefinition & defToUpdate)345 void GLSLProgramManager::convertGLUniformtoOgreType(GLenum gltype, 346 GpuConstantDefinition& defToUpdate) 347 { 348 // Note GLSL never packs rows into float4's (from an API perspective anyway) 349 // therefore all values are tight in the buffer. 350 //TODO Should the rest of the above enum types be included here? 351 switch (gltype) 352 { 353 case GL_FLOAT: 354 defToUpdate.constType = GCT_FLOAT1; 355 break; 356 case GL_FLOAT_VEC2: 357 defToUpdate.constType = GCT_FLOAT2; 358 break; 359 case GL_FLOAT_VEC3: 360 defToUpdate.constType = GCT_FLOAT3; 361 break; 362 case GL_FLOAT_VEC4: 363 defToUpdate.constType = GCT_FLOAT4; 364 break; 365 case GL_IMAGE_1D: //TODO should be its own type? 366 case GL_SAMPLER_1D: 367 case GL_SAMPLER_1D_ARRAY: 368 case GL_INT_SAMPLER_1D: 369 case GL_INT_SAMPLER_1D_ARRAY: 370 case GL_UNSIGNED_INT_SAMPLER_1D: 371 case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY: 372 // need to record samplers for GLSL 373 defToUpdate.constType = GCT_SAMPLER1D; 374 break; 375 case GL_IMAGE_2D: //TODO should be its own type? 376 case GL_IMAGE_2D_RECT: 377 case GL_SAMPLER_2D: 378 case GL_SAMPLER_2D_RECT: // TODO: Move these to a new type?? 379 case GL_INT_SAMPLER_2D_RECT: 380 case GL_UNSIGNED_INT_SAMPLER_2D_RECT: 381 case GL_SAMPLER_2D_ARRAY: 382 case GL_INT_SAMPLER_2D: 383 case GL_INT_SAMPLER_2D_ARRAY: 384 case GL_UNSIGNED_INT_SAMPLER_2D: 385 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: 386 defToUpdate.constType = GCT_SAMPLER2D; 387 break; 388 case GL_IMAGE_3D: //TODO should be its own type? 389 case GL_SAMPLER_3D: 390 case GL_INT_SAMPLER_3D: 391 case GL_UNSIGNED_INT_SAMPLER_3D: 392 defToUpdate.constType = GCT_SAMPLER3D; 393 break; 394 case GL_SAMPLER_CUBE: 395 case GL_SAMPLER_CUBE_SHADOW: 396 case GL_INT_SAMPLER_CUBE: 397 case GL_UNSIGNED_INT_SAMPLER_CUBE: 398 defToUpdate.constType = GCT_SAMPLERCUBE; 399 break; 400 case GL_SAMPLER_1D_SHADOW: 401 case GL_SAMPLER_1D_ARRAY_SHADOW: 402 defToUpdate.constType = GCT_SAMPLER1DSHADOW; 403 break; 404 case GL_SAMPLER_2D_SHADOW: 405 case GL_SAMPLER_2D_RECT_SHADOW: 406 case GL_SAMPLER_2D_ARRAY_SHADOW: 407 defToUpdate.constType = GCT_SAMPLER2DSHADOW; 408 break; 409 case GL_INT: 410 defToUpdate.constType = GCT_INT1; 411 break; 412 case GL_INT_VEC2: 413 defToUpdate.constType = GCT_INT2; 414 break; 415 case GL_INT_VEC3: 416 defToUpdate.constType = GCT_INT3; 417 break; 418 case GL_INT_VEC4: 419 defToUpdate.constType = GCT_INT4; 420 break; 421 case GL_FLOAT_MAT2: 422 defToUpdate.constType = GCT_MATRIX_2X2; 423 break; 424 case GL_FLOAT_MAT3: 425 defToUpdate.constType = GCT_MATRIX_3X3; 426 break; 427 case GL_FLOAT_MAT4: 428 defToUpdate.constType = GCT_MATRIX_4X4; 429 break; 430 case GL_FLOAT_MAT2x3: 431 defToUpdate.constType = GCT_MATRIX_2X3; 432 break; 433 case GL_FLOAT_MAT3x2: 434 defToUpdate.constType = GCT_MATRIX_3X2; 435 break; 436 case GL_FLOAT_MAT2x4: 437 defToUpdate.constType = GCT_MATRIX_2X4; 438 break; 439 case GL_FLOAT_MAT4x2: 440 defToUpdate.constType = GCT_MATRIX_4X2; 441 break; 442 case GL_FLOAT_MAT3x4: 443 defToUpdate.constType = GCT_MATRIX_3X4; 444 break; 445 case GL_FLOAT_MAT4x3: 446 defToUpdate.constType = GCT_MATRIX_4X3; 447 break; 448 case GL_DOUBLE: 449 defToUpdate.constType = GCT_DOUBLE1; 450 break; 451 case GL_DOUBLE_VEC2: 452 defToUpdate.constType = GCT_DOUBLE2; 453 break; 454 case GL_DOUBLE_VEC3: 455 defToUpdate.constType = GCT_DOUBLE3; 456 break; 457 case GL_DOUBLE_VEC4: 458 defToUpdate.constType = GCT_DOUBLE4; 459 break; 460 case GL_DOUBLE_MAT2: 461 defToUpdate.constType = GCT_MATRIX_DOUBLE_2X2; 462 break; 463 case GL_DOUBLE_MAT3: 464 defToUpdate.constType = GCT_MATRIX_DOUBLE_3X3; 465 break; 466 case GL_DOUBLE_MAT4: 467 defToUpdate.constType = GCT_MATRIX_DOUBLE_4X4; 468 break; 469 case GL_DOUBLE_MAT2x3: 470 defToUpdate.constType = GCT_MATRIX_DOUBLE_2X3; 471 break; 472 case GL_DOUBLE_MAT3x2: 473 defToUpdate.constType = GCT_MATRIX_DOUBLE_3X2; 474 break; 475 case GL_DOUBLE_MAT2x4: 476 defToUpdate.constType = GCT_MATRIX_DOUBLE_2X4; 477 break; 478 case GL_DOUBLE_MAT4x2: 479 defToUpdate.constType = GCT_MATRIX_DOUBLE_4X2; 480 break; 481 case GL_DOUBLE_MAT3x4: 482 defToUpdate.constType = GCT_MATRIX_DOUBLE_3X4; 483 break; 484 case GL_DOUBLE_MAT4x3: 485 defToUpdate.constType = GCT_MATRIX_DOUBLE_4X3; 486 break; 487 case GL_UNSIGNED_INT: 488 case GL_UNSIGNED_INT_ATOMIC_COUNTER: //TODO should be its own type? 489 defToUpdate.constType = GCT_UINT1; 490 break; 491 case GL_UNSIGNED_INT_VEC2: 492 defToUpdate.constType = GCT_UINT2; 493 break; 494 case GL_UNSIGNED_INT_VEC3: 495 defToUpdate.constType = GCT_UINT3; 496 break; 497 case GL_UNSIGNED_INT_VEC4: 498 defToUpdate.constType = GCT_UINT4; 499 break; 500 case GL_BOOL: 501 defToUpdate.constType = GCT_BOOL1; 502 break; 503 case GL_BOOL_VEC2: 504 defToUpdate.constType = GCT_BOOL2; 505 break; 506 case GL_BOOL_VEC3: 507 defToUpdate.constType = GCT_BOOL3; 508 break; 509 case GL_BOOL_VEC4: 510 defToUpdate.constType = GCT_BOOL4; 511 break; 512 default: 513 defToUpdate.constType = GCT_UNKNOWN; 514 break; 515 } 516 517 // GL doesn't pad 518 defToUpdate.elementSize = GpuConstantDefinition::getElementSize(defToUpdate.constType, false); 519 } 520 521 findUniformDataSource(const String & paramName,const GpuConstantDefinitionMap * (& constantDefs)[6],GLUniformReference & refToUpdate)522 bool GLSLProgramManager::findUniformDataSource( 523 const String& paramName, 524 const GpuConstantDefinitionMap* (&constantDefs)[6], 525 GLUniformReference& refToUpdate) 526 { 527 for(int i = 0; i < 6; i++) { 528 if (constantDefs[i]) 529 { 530 GpuConstantDefinitionMap::const_iterator parami = 531 constantDefs[i]->find(paramName); 532 if (parami != constantDefs[i]->end()) 533 { 534 refToUpdate.mSourceProgType = static_cast<GpuProgramType>(i); 535 refToUpdate.mConstantDef = &(parami->second); 536 return true; 537 } 538 } 539 } 540 return false; 541 } 542 543 544 //FIXME This is code bloat...either template or unify UniformReference 545 // and AtomicCounterReference findAtomicCounterDataSource(const String & paramName,const GpuConstantDefinitionMap * (& constantDefs)[6],GLAtomicCounterReference & refToUpdate)546 bool GLSLProgramManager::findAtomicCounterDataSource( 547 const String& paramName, 548 const GpuConstantDefinitionMap* (&constantDefs)[6], 549 GLAtomicCounterReference& refToUpdate) 550 { 551 for(int i = 0; i < 6; i++) { 552 if (constantDefs[i]) 553 { 554 GpuConstantDefinitionMap::const_iterator parami = 555 constantDefs[i]->find(paramName); 556 if (parami != constantDefs[i]->end()) 557 { 558 refToUpdate.mSourceProgType = static_cast<GpuProgramType>(i); 559 refToUpdate.mConstantDef = &(parami->second); 560 return true; 561 } 562 } 563 } 564 return false; 565 } 566 567 568 extractUniformsFromProgram(GLuint programObject,const GpuConstantDefinitionMap * (& constantDefs)[6],GLUniformReferenceList & uniformList,GLAtomicCounterReferenceList & counterList,GLUniformBufferList & uniformBufferList,SharedParamsBufferMap & sharedParamsBufferMap,GLCounterBufferList & counterBufferList)569 void GLSLProgramManager::extractUniformsFromProgram( 570 GLuint programObject, 571 const GpuConstantDefinitionMap* (&constantDefs)[6], 572 GLUniformReferenceList& uniformList, 573 GLAtomicCounterReferenceList& counterList, 574 GLUniformBufferList& uniformBufferList, 575 SharedParamsBufferMap& sharedParamsBufferMap, 576 // GLShaderStorageBufferList& shaderStorageBufferList, 577 GLCounterBufferList& counterBufferList) 578 { 579 // Scan through the active uniforms and add them to the reference list. 580 GLint uniformCount = 0; 581 #define uniformLength 200 582 // GLint uniformLength = 0; 583 // glGetProgramiv(programObject, GL_ACTIVE_UNIFORM_MAX_LENGTH, &uniformLength); 584 585 char uniformName[uniformLength]; 586 GLUniformReference newGLUniformReference; 587 GLAtomicCounterReference newGLAtomicCounterReference; 588 589 // Get the number of active uniforms, including atomic 590 // counters and uniforms contained in uniform blocks. 591 OGRE_CHECK_GL_ERROR(glGetProgramiv(programObject, GL_ACTIVE_UNIFORMS, &uniformCount)); 592 593 // Loop over each active uniform and add it to the reference 594 // container. 595 for (GLuint index = 0; index < (GLuint)uniformCount; index++) 596 { 597 GLint arraySize; 598 GLenum glType; 599 OGRE_CHECK_GL_ERROR(glGetActiveUniform(programObject, index, uniformLength, NULL, 600 &arraySize, &glType, uniformName)); 601 602 // Don't add built in uniforms, atomic counters, or uniform block parameters. 603 OGRE_CHECK_GL_ERROR(newGLUniformReference.mLocation = glGetUniformLocation(programObject, uniformName)); 604 if (newGLUniformReference.mLocation >= 0) 605 { 606 // User defined uniform found, add it to the reference list. 607 String paramName = String(uniformName); 608 609 // Current ATI drivers (Catalyst 7.2 and earlier) and 610 // older NVidia drivers will include all array 611 // elements as uniforms but we only want the root 612 // array name and location. Also note that ATI Catalyst 613 // 6.8 to 7.2 there is a bug with glUniform that does 614 // not allow you to update a uniform array past the 615 // first uniform array element ie you can't start 616 // updating an array starting at element 1, must 617 // always be element 0. 618 619 // If the uniform name has a "[" in it then its an array element uniform. 620 String::size_type arrayStart = paramName.find('['); 621 if (arrayStart != String::npos) 622 { 623 // if not the first array element then skip it and continue to the next uniform 624 if (paramName.compare(arrayStart, paramName.size() - 1, "[0]") != 0) continue; 625 paramName = paramName.substr(0, arrayStart); 626 } 627 628 // Find out which params object this comes from 629 bool foundSource = findUniformDataSource(paramName, constantDefs, newGLUniformReference); 630 631 // Only add this parameter if we found the source 632 if (foundSource) 633 { 634 assert(size_t (arraySize) == newGLUniformReference.mConstantDef->arraySize 635 && "GL doesn't agree with our array size!"); 636 uniformList.push_back(newGLUniformReference); 637 } 638 639 // Don't bother adding individual array params, they will be 640 // picked up in the 'parent' parameter can copied all at once 641 // anyway, individual indexes are only needed for lookup from 642 // user params 643 } // end if 644 // Handle atomic counters. Currently atomic counters 645 // cannot be in uniform blocks and are always unsigned 646 // integers. 647 else if (glType == GL_UNSIGNED_INT_ATOMIC_COUNTER) 648 { 649 String paramName = String(uniformName); 650 651 GLint binding, offset; 652 //GLuint indices [] = {index}; 653 OGRE_CHECK_GL_ERROR(glGetActiveUniformsiv(programObject, 1, &index, GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX, &binding)); 654 OGRE_CHECK_GL_ERROR(glGetActiveUniformsiv(programObject, 1, &index, GL_UNIFORM_OFFSET, &offset)); 655 656 newGLAtomicCounterReference.mBinding = binding; 657 newGLAtomicCounterReference.mOffset = offset; 658 659 // increment the total number of atomic counters 660 // including size of array if applicable 661 //atomicCounterCount += arraySize; 662 // actually, this should not be necessary since 663 // parameters are processed one by one 664 665 // If the uniform name has a "[" in it then its an array element uniform. 666 String::size_type arrayStart = paramName.find('['); 667 if (arrayStart != String::npos) 668 { 669 // if not the first array element then skip it and continue to the next uniform 670 if (paramName.compare(arrayStart, paramName.size() - 1, "[0]") != 0) continue; 671 paramName = paramName.substr(0, arrayStart); 672 } 673 674 printf("ATOMIC COUNTER FOUND: %s %d", paramName.c_str(), arraySize); 675 676 // Find out which params object this comes from 677 bool foundSource = findAtomicCounterDataSource( 678 paramName, constantDefs,newGLAtomicCounterReference); 679 680 // Only add this parameter if we found the source 681 if (foundSource) 682 { 683 // size_t adjustedArraySize = 0; 684 // if (arraySize == 2 && newGLAtomicCounterReference.mConstantDef->arraySize == 1) { 685 // adjustedArraySize = 1; 686 // } 687 // else { 688 // adjustedArraySize = (size_t) arraySize; 689 // } 690 691 //FIXME On Linux AMD Catalyst 13.4, OpenGL reports 692 // a single atomic counter as having size 2. Bug 693 // or feature? 694 // assert((size_t)arraySize == newGLAtomicCounterReference.mConstantDef->arraySize 695 // && "GL doesn't agree with our array size!"); 696 697 counterList.push_back(newGLAtomicCounterReference); 698 printf("ATOMIC COUNTER SOURCE FOUND\n"); 699 } 700 } 701 } // end for 702 703 704 //FIXME uniform buffers need to be created during material script parsing of shared params 705 // HardwareUniformBufferSharedPtr newUniformBuffer = HardwareBufferManager::getSingleton().createUniformBuffer(blockSize, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE, false, uniformName); 706 // GL3PlusHardwareUniformBuffer* hwGlBuffer = static_cast<GL3PlusHardwareUniformBuffer*>(newUniformBuffer.get()); 707 // hwGlBuffer->setGLBufferBinding(blockBinding); 708 // GpuSharedParametersPtr blockSharedParams = GpuProgramManager::getSingleton().getSharedParameters(uniformName); 709 // uniformBufferList.push_back(uniformBuffer); 710 711 //FIXME Ogre materials need a new shared param that is associated with an entity. 712 // This could be impemented as a switch-like statement inside shared_params: 713 714 GLint blockCount = 0; 715 716 // Now deal with uniform blocks 717 718 OGRE_CHECK_GL_ERROR(glGetProgramiv(programObject, GL_ACTIVE_UNIFORM_BLOCKS, &blockCount)); 719 720 for (int index = 0; index < blockCount; index++) 721 { 722 OGRE_CHECK_GL_ERROR(glGetActiveUniformBlockName(programObject, index, uniformLength, NULL, uniformName)); 723 724 // Map uniform block to binding point of GL buffer of 725 // shared param bearing the same name. 726 727 GpuSharedParametersPtr blockSharedParams = GpuProgramManager::getSingleton().getSharedParameters(uniformName); 728 //TODO error handling for when buffer has no associated shared parameter? 729 //if (bufferi == mSharedParamGLBufferMap.end()) continue; 730 731 GL3PlusHardwareUniformBuffer* hwGlBuffer; 732 SharedParamsBufferMap::const_iterator bufferMapi = sharedParamsBufferMap.find(blockSharedParams); 733 if (bufferMapi != sharedParamsBufferMap.end()) 734 { 735 hwGlBuffer = static_cast<GL3PlusHardwareUniformBuffer*>(bufferMapi->second.get()); 736 } 737 else 738 { 739 // Create buffer and add entry to buffer map. 740 GLint blockSize; 741 OGRE_CHECK_GL_ERROR(glGetActiveUniformBlockiv(programObject, index, GL_UNIFORM_BLOCK_DATA_SIZE, &blockSize)); 742 HardwareUniformBufferSharedPtr newUniformBuffer = HardwareBufferManager::getSingleton().createUniformBuffer(blockSize, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE, false, uniformName); 743 // bufferMapi->second() = newUniformBuffer; 744 hwGlBuffer = static_cast<GL3PlusHardwareUniformBuffer*>(newUniformBuffer.get()); 745 GLint bufferBinding = sharedParamsBufferMap.size(); 746 hwGlBuffer->setGLBufferBinding(bufferBinding); 747 std::pair<GpuSharedParametersPtr, HardwareUniformBufferSharedPtr> newPair (blockSharedParams, newUniformBuffer); 748 sharedParamsBufferMap.insert(newPair); 749 750 // Get active block parameter properties. 751 GpuConstantDefinitionIterator sharedParamDef = blockSharedParams->getConstantDefinitionIterator(); 752 std::vector<const char*> sharedParamNames; 753 for (; sharedParamDef.current() != sharedParamDef.end(); sharedParamDef.moveNext()) 754 { 755 sharedParamNames.push_back(sharedParamDef.current()->first.c_str()); 756 } 757 758 std::vector<GLuint> uniformParamIndices(sharedParamNames.size()); 759 std::vector<GLint> uniformParamOffsets(sharedParamNames.size()); 760 761 OGRE_CHECK_GL_ERROR(glGetUniformIndices(programObject, sharedParamNames.size(), &sharedParamNames[0], &uniformParamIndices[0])); 762 //FIXME debug this (see stdout) 763 OGRE_CHECK_GL_ERROR(glGetActiveUniformsiv(programObject, uniformParamIndices.size(), &uniformParamIndices[0], GL_UNIFORM_OFFSET, &uniformParamOffsets[0])); 764 //TODO handle uniform arrays 765 //GL_UNIFORM_ARRAY_STRIDE 766 //TODO handle matrices 767 //GL_UNIFORM_MATRIX_STRIDE 768 769 GpuNamedConstants& consts = const_cast<GpuNamedConstants&>(blockSharedParams->getConstantDefinitions()); 770 MapIterator<GpuConstantDefinitionMap> sharedParamDefMut(consts.map); 771 for (size_t i = 0; sharedParamDefMut.current() != sharedParamDefMut.end(); sharedParamDefMut.moveNext(), i++) 772 { 773 // NOTE: the naming in GL3Plus is backward. logicalIndex is actually the physical index of the parameter 774 // while the physicalIndex is the logical array offset.. 775 sharedParamDefMut.current()->second.logicalIndex = uniformParamOffsets[i]; 776 } 777 } 778 779 GLint bufferBinding = hwGlBuffer->getGLBufferBinding(); 780 781 //OGRE_CHECK_GL_ERROR(glGetActiveUniformBlockiv(programObject, index, GL_UNIFORM_BLOCK_BINDING, &blockBinding)); 782 783 OGRE_CHECK_GL_ERROR(glUniformBlockBinding(programObject, index, bufferBinding)); 784 } 785 786 // Now deal with shader storage blocks 787 788 //TODO Need easier, more robust feature checking. 789 // if (mRenderSystem->checkExtension("GL_ARB_program_interface_query") || gl3wIsSupported(4, 3)) 790 if (mRenderSystem->hasMinGLVersion(4, 3)) 791 { 792 OGRE_CHECK_GL_ERROR(glGetProgramInterfaceiv(programObject, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, &blockCount)); 793 794 //TODO error if GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS > # shader_storage_blocks 795 // do same for other buffers 796 797 for (int index = 0; index < blockCount; index++) 798 { 799 //OGRE_CHECK_GL_ERROR(glGetProgramResourceiv(programObject, GL_SHADER_STORAGE_BLOCK, index, uniformName, )); 800 // OGRE_CHECK_GL_ERROR(glGetIntegeri_v(GL_SHADER_STORAGE_BUFFER_BINDING, index, uniformName)); 801 OGRE_CHECK_GL_ERROR(glGetProgramResourceName(programObject, GL_SHADER_STORAGE_BLOCK, index, uniformLength, NULL, uniformName)); 802 803 // Map uniform block to binding point of GL buffer of 804 // shared param bearing the same name. 805 806 GpuSharedParametersPtr blockSharedParams = GpuProgramManager::getSingleton().getSharedParameters(uniformName); 807 //TODO error handling for when buffer has no associated shared parameter? 808 //if (bufferi == mSharedParamGLBufferMap.end()) continue; 809 810 // No more shader storage blocks. 811 // if (uniformName == 0) break; 812 GL3PlusHardwareShaderStorageBuffer* hwGlBuffer; 813 SharedParamsBufferMap::const_iterator bufferMapi = sharedParamsBufferMap.find(blockSharedParams); 814 if (bufferMapi != sharedParamsBufferMap.end()) 815 { 816 hwGlBuffer = static_cast<GL3PlusHardwareShaderStorageBuffer*>(bufferMapi->second.get()); 817 } 818 else 819 { 820 // Create buffer and add entry to buffer map. 821 // bufferMapi->second() = newUniformBuffer; 822 823 GLint blockSize; 824 // const GLenum properties [2] = {GL_BUFFER_DATA_SIZE, GL_BUFFER_BINDING}; 825 GLenum properties[] = {GL_BUFFER_DATA_SIZE}; 826 OGRE_CHECK_GL_ERROR(glGetProgramResourceiv(programObject, GL_SHADER_STORAGE_BLOCK, index, 1, properties, 1, NULL, &blockSize)); 827 //blockSize = properties[0]; 828 //TODO Implement shared param access param in materials (R, W, R+W) 829 // HardwareUniformBufferSharedPtr newShaderStorageBuffer = static_cast<GL3PlusHardwareBufferManager*>(HardwareBufferManager::getSingletonPtr())->createShaderStorageBuffer(blockSize, HardwareBuffer::HBU_DYNAMIC, false, uniformName); 830 HardwareUniformBufferSharedPtr newShaderStorageBuffer = static_cast<GL3PlusHardwareBufferManager*>(HardwareBufferManager::getSingletonPtr())->createShaderStorageBuffer(blockSize, HardwareBuffer::HBU_DYNAMIC, false, uniformName); 831 hwGlBuffer = static_cast<GL3PlusHardwareShaderStorageBuffer*>(newShaderStorageBuffer.get()); 832 833 //FIXME check parameters 834 GLint bufferBinding = sharedParamsBufferMap.size(); 835 hwGlBuffer->setGLBufferBinding(bufferBinding); 836 837 std::pair<GpuSharedParametersPtr, HardwareUniformBufferSharedPtr> newPair (blockSharedParams, newShaderStorageBuffer); 838 sharedParamsBufferMap.insert(newPair); 839 840 // Get active block parameter properties. 841 properties[0] = GL_OFFSET; 842 GpuNamedConstants& consts = const_cast<GpuNamedConstants&>(blockSharedParams->getConstantDefinitions()); 843 MapIterator<GpuConstantDefinitionMap> sharedParamDef(consts.map); 844 for (size_t i = 0; sharedParamDef.current() != sharedParamDef.end(); sharedParamDef.moveNext(), i++) { 845 GLuint varIndex = glGetProgramResourceIndex(programObject, GL_BUFFER_VARIABLE, sharedParamDef.current()->first.c_str()); 846 GLint offset; 847 glGetProgramResourceiv(programObject, GL_BUFFER_VARIABLE, varIndex, 1, properties, 1, NULL, &offset); 848 sharedParamDef.current()->second.logicalIndex = offset; 849 } 850 } 851 852 GLint bufferBinding = hwGlBuffer->getGLBufferBinding(); 853 854 OGRE_CHECK_GL_ERROR(glShaderStorageBlockBinding(programObject, index, bufferBinding)); 855 } 856 } 857 // if (mRenderSystem->checkExtension("GL_ARB_shader_atomic_counters") || gl3wIsSupported(4, 2)) 858 if (mRenderSystem->hasMinGLVersion(4, 2)) 859 { 860 // Now deal with atomic counters buffers 861 OGRE_CHECK_GL_ERROR(glGetProgramiv(programObject, GL_ACTIVE_ATOMIC_COUNTER_BUFFERS, &blockCount)); 862 863 for (int index = 0; index < blockCount; index++) 864 { 865 //TODO Is this necessary? 866 //GpuSharedParametersPtr blockSharedParams = GpuProgramManager::getSingleton().getSharedParameters(uniformName); 867 868 //TODO We could build list of atomic counters here or above, 869 // whichever is most efficient. 870 // GLint * active_indices; 871 // OGRE_CHECK_GL_ERROR(glGetActiveAtomicCounterBufferiv(programObject, index, GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES, active_indices)); 872 873 GLint bufferSize, bufferBinding; 874 OGRE_CHECK_GL_ERROR(glGetActiveAtomicCounterBufferiv(programObject, index, GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE, &bufferSize)); 875 OGRE_CHECK_GL_ERROR(glGetActiveAtomicCounterBufferiv(programObject, index, GL_ATOMIC_COUNTER_BUFFER_BINDING, &bufferBinding)); 876 //TODO check parameters of this GL call 877 HardwareCounterBufferSharedPtr newCounterBuffer = HardwareBufferManager::getSingleton().createCounterBuffer(bufferSize, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE, false); 878 879 GL3PlusHardwareCounterBuffer* hwGlBuffer = static_cast<GL3PlusHardwareCounterBuffer*>(newCounterBuffer.get()); 880 hwGlBuffer->setGLBufferBinding(bufferBinding); 881 counterBufferList.push_back(newCounterBuffer); 882 } 883 } 884 } 885 } 886