void dumpBoolean(StateWriter &writer, GLboolean value) { switch (value) { case GL_FALSE: writer.writeString("GL_FALSE"); break; case GL_TRUE: writer.writeString("GL_TRUE"); break; default: writer.writeInt(static_cast<GLint>(value)); break; } }
static inline void dumpArbProgram(StateWriter &writer, Context &context, GLenum target) { if (context.ES || context.core || !glIsEnabled(target)) { return; } GLint program_length = 0; glGetProgramivARB(target, GL_PROGRAM_LENGTH_ARB, &program_length); if (!program_length) { return; } GLchar *source = new GLchar[program_length + 1]; source[0] = 0; glGetProgramStringARB(target, GL_PROGRAM_STRING_ARB, source); source[program_length] = 0; writer.beginMember(enumToString(target)); writer.writeString(source); writer.endMember(); delete [] source; }
inline void dumpShader(StateWriter &writer, const char *name, T *pShader) { if (!pShader) { return; } /* * There is no method to get the shader byte code, so the creator is supposed to * attach it via the SetPrivateData method. */ std::vector<BYTE> ShaderBytecode = getPrivateData(pShader, GUID_D3DSTATE); if (ShaderBytecode.empty()) { return; } com_ptr<IDisassemblyBuffer> pDisassembly; HRESULT hr; hr = DisassembleShader(&ShaderBytecode[0], ShaderBytecode.size(), &pDisassembly); if (SUCCEEDED(hr)) { writer.beginMember(name); writer.writeString((const char *)pDisassembly->GetBufferPointer() /*, pDisassembly->GetBufferSize() */); writer.endMember(); } }
void dumpEnum(StateWriter &writer, GLenum pname) { const char *s = enumToString(pname); if (s) { writer.writeString(s); } else { writer.writeInt(pname); } }
static inline void dumpProgram(StateWriter &writer, Context &context, GLint program) { if (program <= 0) { return; } GLint attached_shaders = 0; glGetProgramiv(program, GL_ATTACHED_SHADERS, &attached_shaders); if (!attached_shaders) { return; } ShaderMap shaderMap; GLuint *shaders = new GLuint[attached_shaders]; GLsizei count = 0; glGetAttachedShaders(program, attached_shaders, &count, shaders); std::sort(shaders, shaders + count); for (GLsizei i = 0; i < count; ++ i) { getShaderSource(shaderMap, shaders[i]); } delete [] shaders; for (ShaderMap::const_iterator it = shaderMap.begin(); it != shaderMap.end(); ++it) { writer.beginMember(it->first); writer.writeString(it->second); writer.endMember(); } // Dump NVIDIA GPU programs via GL_ARB_get_program_binary if (context.ARB_get_program_binary) { GLint binaryLength = 0; glGetProgramiv(program, GL_PROGRAM_BINARY_LENGTH, &binaryLength); if (binaryLength > 0) { std::vector<char> binary(binaryLength); GLenum format = GL_NONE; glGetProgramBinary(program, binaryLength, NULL, &format, &binary[0]); if (format == 0x8e21) { if (0) { FILE *fp = fopen("program.bin", "wb"); if (fp) { fwrite(&binary[0], 1, binaryLength, fp); fclose(fp); } } // Extract NVIDIA GPU programs std::string str(binary.begin(), binary.end()); size_t end = 0; while (true) { // Each program starts with a !!NV header token size_t start = str.find("!!NV", end); if (start == std::string::npos) { break; } // And is preceeded by a length DWORD assert(start >= end + 4); if (start < end + 4) { break; } uint32_t length; str.copy(reinterpret_cast<char *>(&length), 4, start - 4); assert(start + length <= binaryLength); if (start + length > binaryLength) { break; } std::string nvProg = str.substr(start, length); size_t eol = nvProg.find('\n'); std::string nvHeader = nvProg.substr(2, eol - 2); writer.beginMember(nvHeader); writer.writeString(nvProg); writer.endMember(); end = start + length; } } } } }