| 1263 | |
| 1264 | template <typename SerialiserType> |
| 1265 | bool SerialiseProgramBindings(SerialiserType &ser, CaptureState state, |
| 1266 | const PerStageReflections &stages, GLuint prog) |
| 1267 | { |
| 1268 | rdcarray<ProgramBinding> InputBindings; |
| 1269 | rdcarray<ProgramBinding> OutputBindings; |
| 1270 | |
| 1271 | // technically we can completely skip this if the shaders are SPIR-V, but for compatibility we |
| 1272 | // instead just skip the fetch & apply steps, so that we can still serialise in a backwards |
| 1273 | // compatible way. |
| 1274 | bool IsProgramSPIRV = false; |
| 1275 | for(size_t i = 0; i < NumShaderStages; i++) |
| 1276 | IsProgramSPIRV |= stages.refls[i] && stages.refls[i]->encoding == ShaderEncoding::OpenGLSPIRV; |
| 1277 | |
| 1278 | const bool hasVert = stages.refls[0] != NULL; |
| 1279 | const bool hasFrag = stages.refls[5] != NULL; |
| 1280 | |
| 1281 | if(ser.IsWriting() && !IsProgramSPIRV) |
| 1282 | { |
| 1283 | char buf[128] = {}; |
| 1284 | |
| 1285 | for(int sigType = 0; sigType < 2; sigType++) |
| 1286 | { |
| 1287 | GLenum sigEnum = (sigType == 0 ? eGL_PROGRAM_INPUT : eGL_PROGRAM_OUTPUT); |
| 1288 | rdcarray<ProgramBinding> &bindings = (sigType == 0 ? InputBindings : OutputBindings); |
| 1289 | |
| 1290 | int32_t NumAttributes = 0; |
| 1291 | GL.glGetProgramInterfaceiv(prog, sigEnum, eGL_ACTIVE_RESOURCES, (GLint *)&NumAttributes); |
| 1292 | bindings.reserve(NumAttributes); |
| 1293 | |
| 1294 | for(GLint i = 0; i < NumAttributes; i++) |
| 1295 | { |
| 1296 | GL.glGetProgramResourceName(prog, sigEnum, i, 128, NULL, buf); |
| 1297 | |
| 1298 | ProgramBinding bind; |
| 1299 | bind.Name = buf; |
| 1300 | |
| 1301 | // don't query for gl_ bindings. Serialise it anyway to preserve legacy compatibility, but |
| 1302 | // on replay below we won't try to set this binding either |
| 1303 | if(bind.Name.beginsWith("gl_")) |
| 1304 | { |
| 1305 | bind.Binding = -1; |
| 1306 | } |
| 1307 | else |
| 1308 | { |
| 1309 | if(sigType == 0) |
| 1310 | bind.Binding = GL.glGetAttribLocation(prog, buf); |
| 1311 | else |
| 1312 | bind.Binding = GL.glGetFragDataLocation(prog, buf); |
| 1313 | } |
| 1314 | |
| 1315 | bindings.push_back(bind); |
| 1316 | } |
| 1317 | } |
| 1318 | } |
| 1319 | |
| 1320 | SERIALISE_ELEMENT(InputBindings); |
| 1321 | SERIALISE_ELEMENT(OutputBindings); |
| 1322 |
no test coverage detected