static void dumpShaders(StateWriter &writer, ID3D10Device *pDevice) { writer.beginMember("shaders"); writer.beginObject(); com_ptr<ID3D10VertexShader> pVertexShader; pDevice->VSGetShader(&pVertexShader); if (pVertexShader) { dumpShader<ID3D10DeviceChild>(writer, "VS", pVertexShader); } com_ptr<ID3D10GeometryShader> pGeometryShader; pDevice->GSGetShader(&pGeometryShader); if (pGeometryShader) { dumpShader<ID3D10DeviceChild>(writer, "GS", pGeometryShader); } com_ptr<ID3D10PixelShader> pPixelShader; pDevice->PSGetShader(&pPixelShader); if (pPixelShader) { dumpShader<ID3D10DeviceChild>(writer, "PS", pPixelShader); } writer.endObject(); writer.endMember(); // shaders }
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(); } }
// DebugAllocator::dump_state void DebugAllocator::dump_state( StateWriter & i_state_writer ) { i_state_writer.write( "type", "debug" ); i_state_writer.write_mem_size( "heading_nomansland_size", m_heading_nomansland_size ); i_state_writer.write_mem_size( "tailing_nomansland_size", m_tailing_nomansland_size ); DecoratorAllocator::dump_state( i_state_writer ); }
void dumpEnum(StateWriter &writer, GLenum pname) { const char *s = enumToString(pname); if (s) { writer.writeString(s); } else { writer.writeInt(pname); } }
static void dumpRasterizerState(StateWriter &writer, ID3D10Device *pDevice) { com_ptr<ID3D10RasterizerState> pRasterizerState; pDevice->RSGetState(&pRasterizerState); writer.beginMember("RasterizerState"); dumpStateObjectDesc(writer, pRasterizerState); writer.endMember(); // RasterizerState }
static void dumpDepthStencilState(StateWriter &writer, ID3D10Device *pDevice) { com_ptr<ID3D10DepthStencilState> pDepthStencilState; UINT stencilRef; pDevice->OMGetDepthStencilState(&pDepthStencilState, &stencilRef); writer.beginMember("DepthStencilState"); dumpStateObjectDesc(writer, pDepthStencilState); writer.endMember(); // DepthStencilState writer.writeIntMember("StencilRef", stencilRef); }
// DecoratorAllocator::dump_state void DecoratorAllocator::dump_state( StateWriter & i_state_writer ) { if( m_dest_allocator != nullptr ) { i_state_writer.tab( "allocator" ); m_dest_allocator->dump_state( i_state_writer ); i_state_writer.untab(); } else { i_state_writer.write( "target", "null" ); } }
static void dumpProgramUniformsStage(StateWriter &writer, GLint program, const char *stage) { if (program <= 0) { return; } writer.beginMember(stage); writer.beginObject(); dumpProgramUniforms(writer, program); writer.endObject(); writer.endMember(); }
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 void dumpParameters(StateWriter &writer, ID3D10Device *pDevice) { // TODO: dump description of current bound state writer.beginMember("parameters"); writer.beginObject(); dumpRasterizerState(writer, pDevice); dumpBlendState(writer, pDevice); dumpDepthStencilState(writer, pDevice); dumpViewports(writer, pDevice); dumpScissors(writer, pDevice); writer.endObject(); writer.endMember(); // parameters }
void dumpFramebuffer(StateWriter &writer, ID3D10Device *pDevice) { writer.beginMember("framebuffer"); writer.beginObject(); ID3D10RenderTargetView *pRenderTargetViews[D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT]; ID3D10DepthStencilView *pDepthStencilView; pDevice->OMGetRenderTargets(ARRAYSIZE(pRenderTargetViews), pRenderTargetViews, &pDepthStencilView); for (UINT i = 0; i < ARRAYSIZE(pRenderTargetViews); ++i) { if (!pRenderTargetViews[i]) { continue; } image::Image *image; image = getRenderTargetViewImage(pDevice, pRenderTargetViews[i]); if (image) { char label[64]; _snprintf(label, sizeof label, "RENDER_TARGET_%u", i); writer.beginMember(label); writer.writeImage(image); writer.endMember(); // RENDER_TARGET_* delete image; } pRenderTargetViews[i]->Release(); } if (pDepthStencilView) { image::Image *image; image = getDepthStencilViewImage(pDevice, pDepthStencilView); if (image) { writer.beginMember("DEPTH_STENCIL"); writer.writeImage(image); writer.endMember(); delete image; } pDepthStencilView->Release(); } writer.endObject(); writer.endMember(); // framebuffer }
static void dumpViewports(StateWriter &writer, ID3D10Device *pDevice) { D3D10_VIEWPORT vps[D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; UINT numViewports = 0, i; pDevice->RSGetViewports(&numViewports, NULL); pDevice->RSGetViewports(&numViewports, vps); writer.beginMember("Viewports"); writer.beginArray(); for (i = 0; i < numViewports; ++i) { dumpStateObject(writer, vps[i]); } writer.endArray(); writer.endMember(); }
static void dumpScissors(StateWriter &writer, ID3D10Device *pDevice) { D3D10_RECT rects[D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; UINT numRects = 0, i; pDevice->RSGetScissorRects(&numRects, NULL); pDevice->RSGetScissorRects(&numRects, rects); writer.beginMember("Scissors"); writer.beginArray(); for (i = 0; i < numRects; ++i) { dumpStateObject(writer, rects[i]); } writer.endArray(); writer.endMember(); }
/** * Dump a GL_KHR_debug/GL_EXT_debug_label object label. */ void dumpObjectLabel(StateWriter &writer, Context &context, GLenum identifier, GLuint name, const char *member) { char *label = getObjectLabel(context, identifier, name); if (!label) { return; } writer.writeStringMember(member, label); free(label); }
void dumpTextures(StateWriter &writer, ID3D10Device *pDevice) { writer.beginMember("textures"); writer.beginObject(); ID3D10ShaderResourceView *pShaderResourceViews[D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT]; pDevice->PSGetShaderResources(0, ARRAYSIZE(pShaderResourceViews), pShaderResourceViews); dumpStageTextures(writer, pDevice, "PS", ARRAYSIZE(pShaderResourceViews), pShaderResourceViews); pDevice->VSGetShaderResources(0, ARRAYSIZE(pShaderResourceViews), pShaderResourceViews); dumpStageTextures(writer, pDevice, "VS", ARRAYSIZE(pShaderResourceViews), pShaderResourceViews); pDevice->GSGetShaderResources(0, ARRAYSIZE(pShaderResourceViews), pShaderResourceViews); dumpStageTextures(writer, pDevice, "GS", ARRAYSIZE(pShaderResourceViews), pShaderResourceViews); writer.endObject(); writer.endMember(); // textures }
static void dumpAttribArray(StateWriter &writer, const std::string & name, const AttribDesc &desc, const GLbyte *data) { writer.beginMember(name); if (desc.size > 1) { writer.beginArray(); } for (GLint i = 0; i < desc.size; ++i) { const GLbyte *row = data + desc.arrayStride*i; dumpAttrib(writer, desc, row); } if (desc.size > 1) { writer.endArray(); } writer.endMember(); }
void dumpFramebuffer(StateWriter &writer, IDirect3DDevice8 *pDevice) { HRESULT hr; writer.beginMember("framebuffer"); writer.beginObject(); com_ptr<IDirect3DSurface8> pRenderTarget; hr = pDevice->GetRenderTarget(&pRenderTarget); if (SUCCEEDED(hr) && pRenderTarget) { image::Image *image; image = getRenderTargetImage(pDevice, pRenderTarget); if (image) { writer.beginMember("RENDER_TARGET_0"); writer.writeImage(image); writer.endMember(); // RENDER_TARGET_* delete image; } } com_ptr<IDirect3DSurface8> pDepthStencil; hr = pDevice->GetDepthStencilSurface(&pDepthStencil); if (SUCCEEDED(hr) && pDepthStencil) { image::Image *image; image = getSurfaceImage(pDevice, pDepthStencil); if (image) { writer.beginMember("DEPTH_STENCIL"); writer.writeImage(image); writer.endMember(); // RENDER_TARGET_* delete image; } } writer.endObject(); writer.endMember(); // framebuffer }
void dumpTextures(StateWriter &writer, IDirect3DDevice8 *pDevice) { HRESULT hr; writer.beginMember("textures"); writer.beginObject(); for (DWORD Stage = 0; Stage < 8; ++Stage) { com_ptr<IDirect3DBaseTexture8> pTexture; hr = pDevice->GetTexture(Stage, &pTexture); if (FAILED(hr)) { continue; } if (!pTexture) { continue; } D3DRESOURCETYPE Type = pTexture->GetType(); DWORD NumFaces = Type == D3DRTYPE_CUBETEXTURE ? 6 : 1; DWORD NumLevels = pTexture->GetLevelCount(); for (DWORD Face = 0; Face < NumFaces; ++Face) { for (DWORD Level = 0; Level < NumLevels; ++Level) { image::Image *image; image = getTextureImage(pDevice, pTexture, static_cast<D3DCUBEMAP_FACES>(Face), Level); if (image) { char label[128]; if (Type == D3DRTYPE_CUBETEXTURE) { _snprintf(label, sizeof label, "PS_RESOURCE_%lu_FACE_%lu_LEVEL_%lu", Stage, Face, Level); } else { _snprintf(label, sizeof label, "PS_RESOURCE_%lu_LEVEL_%lu", Stage, Level); } writer.beginMember(label); writer.writeImage(image); writer.endMember(); // PS_RESOURCE_* delete image; } } } } writer.endObject(); writer.endMember(); // textures }
static void dumpBlendState(StateWriter &writer, ID3D10Device *pDevice) { com_ptr<ID3D10BlendState> pBlendState; FLOAT BlendFactor[4]; UINT SampleMask; pDevice->OMGetBlendState(&pBlendState, BlendFactor, &SampleMask); writer.beginMember("BlendState"); dumpStateObjectDesc(writer, pBlendState); writer.endMember(); // BlendState writer.beginMember("BlendFactor"); writer.beginArray(); writer.writeFloat(BlendFactor[0]); writer.writeFloat(BlendFactor[1]); writer.writeFloat(BlendFactor[2]); writer.writeFloat(BlendFactor[3]); writer.endArray(); writer.endMember(); // BlendFactor writer.writeIntMember("SampleMask", SampleMask); }
void dumpShadersUniforms(StateWriter &writer, Context &context) { GLint pipeline = 0; GLint vertex_program = 0; GLint fragment_program = 0; GLint geometry_program = 0; GLint tess_control_program = 0; GLint tess_evaluation_program = 0; GLint compute_program = 0; if (!context.ES) { glGetIntegerv(GL_PROGRAM_PIPELINE_BINDING, &pipeline); if (pipeline) { glGetProgramPipelineiv(pipeline, GL_VERTEX_SHADER, &vertex_program); glGetProgramPipelineiv(pipeline, GL_FRAGMENT_SHADER, &fragment_program); glGetProgramPipelineiv(pipeline, GL_GEOMETRY_SHADER, &geometry_program); glGetProgramPipelineiv(pipeline, GL_TESS_CONTROL_SHADER, &tess_control_program); glGetProgramPipelineiv(pipeline, GL_TESS_EVALUATION_SHADER, &tess_evaluation_program); glGetProgramPipelineiv(pipeline, GL_COMPUTE_SHADER, &compute_program); } } GLint program = 0; if (!pipeline) { glGetIntegerv(GL_CURRENT_PROGRAM, &program); } writer.beginMember("shaders"); writer.beginObject(); if (pipeline) { dumpProgram(writer, context, vertex_program); dumpProgram(writer, context, fragment_program); dumpProgram(writer, context, geometry_program); dumpProgram(writer, context, tess_control_program); dumpProgram(writer, context, tess_evaluation_program); dumpProgram(writer, context, compute_program); } else if (program) { dumpProgram(writer, context, program); } else { dumpArbProgram(writer, context, GL_FRAGMENT_PROGRAM_ARB); dumpArbProgram(writer, context, GL_VERTEX_PROGRAM_ARB); } writer.endObject(); writer.endMember(); // shaders writer.beginMember("uniforms"); writer.beginObject(); if (pipeline) { dumpProgramUniformsStage(writer, vertex_program, "GL_VERTEX_SHADER"); dumpProgramUniformsStage(writer, fragment_program, "GL_FRAGMENT_SHADER"); dumpProgramUniformsStage(writer, geometry_program, "GL_GEOMETRY_SHADER"); dumpProgramUniformsStage(writer, tess_control_program, "GL_TESS_CONTROL_SHADER"); dumpProgramUniformsStage(writer, tess_evaluation_program, "GL_TESS_EVALUATION_SHADER"); dumpProgramUniformsStage(writer, compute_program, "GL_COMPUTE_SHADER"); } else if (program) { dumpProgramUniforms(writer, program); } else { dumpArbProgramUniforms(writer, context, GL_FRAGMENT_PROGRAM_ARB, "fp."); dumpArbProgramUniforms(writer, context, GL_VERTEX_PROGRAM_ARB, "vp."); } writer.endObject(); writer.endMember(); // uniforms writer.beginMember("buffers"); writer.beginObject(); if (!context.ES) { if (pipeline) { dumpVertexAttributes(writer, context, vertex_program); } else { dumpVertexAttributes(writer, context, program); } if (program) { dumpTransformFeedback(writer, program); } } writer.endObject(); writer.endMember(); // buffers }
static void dumpVertexAttributes(StateWriter &writer, Context &context, GLint program) { if (program <= 0) { return; } GLint activeAttribs = 0; glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &activeAttribs); if (!activeAttribs) { return; } GLint max_name_length = 0; glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_name_length); std::vector<GLchar> name(max_name_length); std::map<GLuint, BufferMapping> mappings; std::vector<VertexAttrib> attribs; unsigned count = ~0U; for (GLint index = 0; index < activeAttribs; ++index) { GLsizei length = 0; GLint shaderSize = 0; GLenum shaderType = GL_NONE; glGetActiveAttrib(program, index, max_name_length, &length, &shaderSize, &shaderType, &name[0]); if (isBuiltinName(&name[0])) { // TODO: Handle built-ins too std::cerr << "warning: dumping of built-in vertex attribute (" << &name[0] << ") not yet supported\n"; continue; } GLint location = glGetAttribLocation(program, &name[0]); if (location < 0) { continue; } GLint buffer = 0; glGetVertexAttribiv(location, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &buffer); if (!buffer) { continue; } GLint size = 0; glGetVertexAttribiv(location, GL_VERTEX_ATTRIB_ARRAY_SIZE, &size); GLint type = 0; glGetVertexAttribiv(location, GL_VERTEX_ATTRIB_ARRAY_TYPE, &type); GLint normalized = 0; glGetVertexAttribiv(location, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &normalized); GLint stride = 0; glGetVertexAttribiv(location, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &stride); GLvoid * pointer = 0; glGetVertexAttribPointerv(location, GL_VERTEX_ATTRIB_ARRAY_POINTER, &pointer); GLint offset = reinterpret_cast<intptr_t>(pointer); assert(offset >= 0); GLint divisor = 0; glGetVertexAttribiv(location, GL_VERTEX_ATTRIB_ARRAY_DIVISOR, &divisor); if (divisor) { // TODO: not clear the best way of presenting instanced attibutes on the dump std::cerr << "warning: dumping of instanced attributes (" << &name[0] << ") not yet supported\n"; return; } if (size == GL_BGRA) { std::cerr << "warning: dumping of GL_BGRA attributes (" << &name[0] << ") not yet supported\n"; size = 4; } AttribDesc desc(type, size); if (!desc) { std::cerr << "warning: dumping of packed attribute (" << &name[0] << ") not yet supported\n"; // TODO: handle continue; } attribs.emplace_back(); VertexAttrib &attrib = attribs.back(); attrib.name = &name[0]; // TODO handle normalized attributes if (normalized) { std::cerr << "warning: dumping of normalized attribute (" << &name[0] << ") not yet supported\n"; } attrib.desc = desc; GLsizei attribSize = attrib.desc.arrayStride; if (stride == 0) { // tightly packed stride = attribSize; } attrib.offset = offset; attrib.stride = stride; BufferMapping &mapping = mappings[buffer]; attrib.map = (const GLbyte *)mapping.map(GL_ARRAY_BUFFER, buffer); BufferBinding bb(GL_ARRAY_BUFFER, buffer); GLint bufferSize = 0; glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &bufferSize); if (bufferSize <= offset || bufferSize <= offset + attribSize) { return; } else { unsigned attribCount = (bufferSize - offset - attribSize)/stride + 1; count = std::min(count, attribCount); } } if (count == 0 || count == ~0U || attribs.empty()) { return; } writer.beginMember("vertices"); writer.beginArray(); for (unsigned vertex = 0; vertex < count; ++vertex) { writer.beginObject(); for (auto attrib : attribs) { const AttribDesc & desc = attrib.desc; assert(desc); const GLbyte *vertex_data = attrib.map + attrib.stride*vertex + attrib.offset; dumpAttribArray(writer, attrib.name, desc, vertex_data); } writer.endObject(); } writer.endArray(); writer.endMember(); }
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; } } } } }
static inline void dumpArbProgramUniforms(StateWriter &writer, Context &context, GLenum target, const char *prefix) { if (context.ES || context.core || !glIsEnabled(target)) { return; } GLint program_parameters = 0; glGetProgramivARB(target, GL_PROGRAM_PARAMETERS_ARB, &program_parameters); if (!program_parameters) { return; } GLint max_program_local_parameters = 0; glGetProgramivARB(target, GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, &max_program_local_parameters); for (GLint index = 0; index < max_program_local_parameters; ++index) { GLdouble params[4] = {0, 0, 0, 0}; glGetProgramLocalParameterdvARB(target, index, params); if (!params[0] && !params[1] && !params[2] && !params[3]) { continue; } char name[256]; snprintf(name, sizeof name, "%sprogram.local[%i]", prefix, index); writer.beginMember(name); writer.beginArray(); writer.writeFloat(params[0]); writer.writeFloat(params[1]); writer.writeFloat(params[2]); writer.writeFloat(params[3]); writer.endArray(); writer.endMember(); } GLint max_program_env_parameters = 0; glGetProgramivARB(target, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &max_program_env_parameters); for (GLint index = 0; index < max_program_env_parameters; ++index) { GLdouble params[4] = {0, 0, 0, 0}; glGetProgramEnvParameterdvARB(target, index, params); if (!params[0] && !params[1] && !params[2] && !params[3]) { continue; } char name[256]; snprintf(name, sizeof name, "%sprogram.env[%i]", prefix, index); writer.beginMember(name); writer.beginArray(); writer.writeFloat(params[0]); writer.writeFloat(params[1]); writer.writeFloat(params[2]); writer.writeFloat(params[3]); writer.endArray(); writer.endMember(); } }
static inline void dumpTransformFeedback(StateWriter &writer, GLint program) { GLint transform_feedback_varyings = 0; glGetProgramiv(program, GL_TRANSFORM_FEEDBACK_VARYINGS, &transform_feedback_varyings); if (!transform_feedback_varyings) { return; } GLint max_name_length = 0; glGetProgramiv(program, GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, &max_name_length); std::vector<GLchar> name(max_name_length); GLint buffer_mode = GL_INTERLEAVED_ATTRIBS; glGetProgramiv(program, GL_TRANSFORM_FEEDBACK_BUFFER_MODE, &buffer_mode); std::vector<TransformFeedbackAttrib> attribs(transform_feedback_varyings); // Calculate the offsets and strides of each attribute according to // the value of GL_TRANSFORM_FEEDBACK_BUFFER_MODE GLsizei cum_attrib_offset = 0; for (GLint slot = 0; slot < transform_feedback_varyings; ++slot) { TransformFeedbackAttrib & attrib = attribs[slot]; GLsizei length = 0; GLsizei size = 0; GLenum type = GL_NONE; glGetTransformFeedbackVarying(program, slot, max_name_length, &length, &size, &type, &name[0]); attrib.name = &name[0]; const AttribDesc & desc = attrib.desc = AttribDesc(type, size); if (!desc) { return; } attrib.size = desc.arrayStride; switch (buffer_mode) { case GL_INTERLEAVED_ATTRIBS: attrib.offset = cum_attrib_offset; break; case GL_SEPARATE_ATTRIBS: attrib.offset = 0; attrib.stride = desc.arrayStride; break; default: assert(0); attrib.offset = 0; attrib.stride = 0; } cum_attrib_offset += desc.arrayStride; } if (buffer_mode == GL_INTERLEAVED_ATTRIBS) { for (GLint slot = 0; slot < transform_feedback_varyings; ++slot) { TransformFeedbackAttrib & attrib = attribs[slot]; attrib.stride = cum_attrib_offset; } } GLint previous_tbo = 0; glGetIntegerv(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, &previous_tbo); // Map the buffers and calculate how many vertices can they hold // XXX: We currently limit to 1024, or things can get significantly slow. unsigned numVertices = 16*1024; for (GLint slot = 0; slot < transform_feedback_varyings; ++slot) { TransformFeedbackAttrib & attrib = attribs[slot]; attrib.map = NULL; if (slot == 0 || buffer_mode != GL_INTERLEAVED_ATTRIBS) { GLint tbo = 0; glGetIntegeri_v(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, slot, &tbo); if (!tbo) { numVertices = 0; continue; } GLint start = 0; glGetIntegeri_v(GL_TRANSFORM_FEEDBACK_BUFFER_START, slot, &start); GLint size = 0; glGetIntegeri_v(GL_TRANSFORM_FEEDBACK_BUFFER_SIZE, slot, &size); glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, tbo); if (size == 0) { glGetBufferParameteriv(GL_TRANSFORM_FEEDBACK_BUFFER, GL_BUFFER_SIZE, &size); assert(size >= start); size -= start; } unsigned numAttribVertices = calcNumElements(size, attrib.offset, attrib.size, attrib.stride); numVertices = std::min(numVertices, numAttribVertices); attrib.map = (const GLbyte *)attrib.mapping.map(GL_TRANSFORM_FEEDBACK_BUFFER, tbo) + start; } else { attrib.map = attribs[0].map; } } glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, previous_tbo); // Actually dump the vertices writer.beginMember("GL_TRANSFORM_FEEDBACK"); writer.beginArray(); for (unsigned vertex = 0; vertex < numVertices; ++vertex) { writer.beginObject(); for (GLint slot = 0; slot < transform_feedback_varyings; ++slot) { TransformFeedbackAttrib & attrib = attribs[slot]; if (!attrib.map) { continue; } const AttribDesc & desc = attrib.desc; assert(desc); const GLbyte *vertex_data = attrib.map + attrib.stride*vertex + attrib.offset; dumpAttribArray(writer, attrib.name, desc, vertex_data); } writer.endObject(); } writer.endArray(); writer.endMember(); }
static void dumpUniform(StateWriter &writer, GLint program, const AttribDesc & desc, const GLchar *name) { if (desc.elemType == GL_NONE) { return; } union { GLfloat fvalues[4*4]; GLdouble dvalues[4*4]; GLint ivalues[4*4]; GLuint uivalues[4*4]; GLint64 i64values[4*4]; GLuint64 ui64values[4*4]; GLbyte data[4*4*4]; } u; GLint i; std::string qualifiedName = resolveUniformName(name, desc.size); writer.beginMember(qualifiedName); if (desc.size > 1) { writer.beginArray(); } for (i = 0; i < desc.size; ++i) { std::stringstream ss; ss << qualifiedName; if (desc.size > 1) { ss << '[' << i << ']'; } std::string elemName = ss.str(); GLint location = glGetUniformLocation(program, elemName.c_str()); assert(location != -1); if (location == -1) { continue; } switch (desc.elemType) { case GL_FLOAT: glGetUniformfv(program, location, u.fvalues); break; case GL_DOUBLE: glGetUniformdv(program, location, u.dvalues); break; case GL_INT: glGetUniformiv(program, location, u.ivalues); break; case GL_UNSIGNED_INT: glGetUniformuiv(program, location, u.uivalues); break; case GL_INT64_ARB: glGetUniformi64vARB(program, location, u.i64values); break; case GL_UNSIGNED_INT64_ARB: glGetUniformui64vARB(program, location, u.ui64values); break; case GL_BOOL: glGetUniformiv(program, location, u.ivalues); break; default: assert(0); break; } dumpAttrib(writer, desc, u.data); } if (desc.size > 1) { writer.endArray(); } writer.endMember(); }
static void dumpAttrib(StateWriter &writer, const AttribDesc &desc, const GLbyte *data) { assert(desc); if (desc.numRows > 1) { writer.beginArray(); } for (GLint row = 0; row < desc.numRows; ++row) { if (desc.numCols > 1) { writer.beginArray(); } for (GLint col = 0; col < desc.numCols; ++col) { union { const GLbyte *rawvalue; const GLfloat *fvalue; const GLdouble *dvalue; const GLint *ivalue; const GLuint *uivalue; const GLint64 *i64value; const GLuint64 *ui64value; } u; u.rawvalue = data + row*desc.rowStride + col*desc.colStride; switch (desc.elemType) { case GL_FLOAT: writer.writeFloat(*u.fvalue); break; case GL_DOUBLE: writer.writeFloat(*u.dvalue); break; case GL_INT: writer.writeInt(*u.ivalue); break; case GL_UNSIGNED_INT: writer.writeInt(*u.uivalue); break; case GL_INT64_ARB: writer.writeInt(*u.i64value); break; case GL_UNSIGNED_INT64_ARB: writer.writeInt(*u.ui64value); break; case GL_BOOL: writer.writeBool(*u.uivalue); break; default: assert(0); writer.writeNull(); break; } } if (desc.numCols > 1) { writer.endArray(); } } if (desc.numRows > 1) { writer.endArray(); } }
EStatusCode PDFWriter::Shutdown(const std::string& inStateFilePath) { EStatusCode status; do { StateWriter writer; status = writer.Start(inStateFilePath); if(status != eSuccess) { TRACE_LOG("PDFWriter::Shutdown, cant start state writing"); break; } ObjectIDType rootObjectID = writer.GetObjectsWriter()->StartNewIndirectObject(); DictionaryContext* pdfWriterDictionary = writer.GetObjectsWriter()->StartDictionary(); pdfWriterDictionary->WriteKey("Type"); pdfWriterDictionary->WriteNameValue("PDFWriter"); ObjectIDType objectsContextID = writer.GetObjectsWriter()->GetInDirectObjectsRegistry().AllocateNewObjectID(); ObjectIDType DocumentContextID = writer.GetObjectsWriter()->GetInDirectObjectsRegistry().AllocateNewObjectID(); pdfWriterDictionary->WriteKey("mObjectsContext"); pdfWriterDictionary->WriteNewObjectReferenceValue(objectsContextID); pdfWriterDictionary->WriteKey("mDocumentContext"); pdfWriterDictionary->WriteNewObjectReferenceValue(DocumentContextID); pdfWriterDictionary->WriteKey("mIsModified"); pdfWriterDictionary->WriteBooleanValue(mIsModified); if(mIsModified) { pdfWriterDictionary->WriteKey("mModifiedFileVersion"); pdfWriterDictionary->WriteIntegerValue(mModifiedFileVersion); } writer.GetObjectsWriter()->EndDictionary(pdfWriterDictionary); writer.GetObjectsWriter()->EndIndirectObject(); writer.SetRootObject(rootObjectID); status = mObjectsContext.WriteState(writer.GetObjectsWriter(),objectsContextID); if(status != eSuccess) break; status = mDocumentContext.WriteState(writer.GetObjectsWriter(),DocumentContextID); if(status != eSuccess) break; status = writer.Finish(); if(status != eSuccess) { TRACE_LOG("PDFWriter::Shutdown, cant finish state writing"); } }while(false); if(status != eSuccess) { mOutputFile.CloseFile(); TRACE_LOG("PDFWriter::Shutdown, Could not end PDF"); } else status = mOutputFile.CloseFile(); //ReleaseLog(); return status; }
static void dumpShaderResourceViewImage(StateWriter &writer, ID3D10Device *pDevice, ID3D10ShaderResourceView *pShaderResourceView, const char *shader, UINT stage) { if (!pShaderResourceView) { return; } com_ptr<ID3D10Resource> pResource; pShaderResourceView->GetResource(&pResource); assert(pResource); D3D10_SHADER_RESOURCE_VIEW_DESC Desc; pShaderResourceView->GetDesc(&Desc); UINT MipSlice = 0; UINT FirstArraySlice = 0; UINT ArraySize = 1; switch (Desc.ViewDimension) { case D3D10_SRV_DIMENSION_BUFFER: break; case D3D10_SRV_DIMENSION_TEXTURE1D: MipSlice = Desc.Texture1D.MostDetailedMip; break; case D3D10_SRV_DIMENSION_TEXTURE1DARRAY: MipSlice = Desc.Texture1DArray.MostDetailedMip; FirstArraySlice = Desc.Texture1DArray.FirstArraySlice; ArraySize = Desc.Texture1DArray.ArraySize; break; case D3D10_SRV_DIMENSION_TEXTURE2D: MipSlice = Desc.Texture2D.MostDetailedMip; break; case D3D10_SRV_DIMENSION_TEXTURE2DARRAY: MipSlice = Desc.Texture2DArray.MostDetailedMip; FirstArraySlice = Desc.Texture2DArray.FirstArraySlice; ArraySize = Desc.Texture2DArray.ArraySize; break; case D3D10_SRV_DIMENSION_TEXTURE2DMS: break; case D3D10_SRV_DIMENSION_TEXTURE2DMSARRAY: FirstArraySlice = Desc.Texture2DMSArray.FirstArraySlice; ArraySize = Desc.Texture2DMSArray.ArraySize; break; case D3D10_SRV_DIMENSION_TEXTURE3D: MipSlice = Desc.Texture3D.MostDetailedMip; break; case D3D10_SRV_DIMENSION_TEXTURECUBE: MipSlice = Desc.TextureCube.MostDetailedMip; ArraySize = 6; break; case D3D10_SRV_DIMENSION_UNKNOWN: default: assert(0); return; } for (UINT ArraySlice = FirstArraySlice; ArraySlice < FirstArraySlice + ArraySize; ++ArraySlice) { image::Image *image; image = getSubResourceImage(pDevice, pResource, Desc.Format, ArraySlice, MipSlice); if (image) { char label[64]; _snprintf(label, sizeof label, "%s_RESOURCE_%u_ARRAY_%u_LEVEL_%u", shader, stage, ArraySlice, MipSlice); writer.beginMember(label); writer.writeImage(image); writer.endMember(); // *_RESOURCE_* delete image; } } }