void WrappedOpenGL::glSamplerParameterIuiv(GLuint sampler, GLenum pname, const GLuint *params) { m_Real.glSamplerParameterIuiv(sampler, pname, params); GLuint clamptoedge[4] = {eGL_CLAMP_TO_EDGE}; // CLAMP isn't supported (border texels gone), assume they meant CLAMP_TO_EDGE if(*params == eGL_CLAMP) params = clamptoedge; if(m_State >= WRITING) { SCOPED_SERIALISE_CONTEXT(SAMPLER_PARAMETERIUIV); Serialise_glSamplerParameterIuiv(sampler, pname, params); if(m_State == WRITING_IDLE) { GetResourceManager()->GetResourceRecord(SamplerRes(GetCtx(), sampler))->AddChunk(scope.Get()); } else { m_ContextRecord->AddChunk(scope.Get()); GetResourceManager()->MarkResourceFrameReferenced(SamplerRes(GetCtx(), sampler), eFrameRef_Read); } } }
void WrappedOpenGL::glSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) { m_Real.glSamplerParameterf(sampler, pname, param); // CLAMP isn't supported (border texels gone), assume they meant CLAMP_TO_EDGE if(param == (float)eGL_CLAMP) param = (float)eGL_CLAMP_TO_EDGE; if(m_State >= WRITING) { SCOPED_SERIALISE_CONTEXT(SAMPLER_PARAMETERF); Serialise_glSamplerParameterf(sampler, pname, param); if(m_State == WRITING_IDLE) { GetResourceManager()->GetResourceRecord(SamplerRes(GetCtx(), sampler))->AddChunk(scope.Get()); } else { m_ContextRecord->AddChunk(scope.Get()); GetResourceManager()->MarkResourceFrameReferenced(SamplerRes(GetCtx(), sampler), eFrameRef_Read); } } }
void WrappedOpenGL::glCreateSamplers(GLsizei count, GLuint *samplers) { m_Real.glCreateSamplers(count, samplers); for(GLsizei i = 0; i < count; i++) { GLResource res = SamplerRes(GetCtx(), samplers[i]); ResourceId id = GetResourceManager()->RegisterResource(res); if(m_State >= WRITING) { Chunk *chunk = NULL; { SCOPED_SERIALISE_CONTEXT(CREATE_SAMPLERS); Serialise_glCreateSamplers(1, samplers + i); chunk = scope.Get(); } GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); RDCASSERT(record); record->AddChunk(chunk); } else { GetResourceManager()->AddLiveResource(id, res); } } }
bool WrappedOpenGL::Serialise_glSamplerParameteri(GLuint sampler, GLenum pname, GLint param) { SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(SamplerRes(GetCtx(), sampler))); SERIALISE_ELEMENT(GLenum, PName, pname); int32_t ParamValue = 0; RDCCOMPILE_ASSERT(sizeof(int32_t) == sizeof(GLenum), "int32_t isn't the same size as GLenum - aliased serialising will break"); // special case a few parameters to serialise their value as an enum, not an int if(PName == GL_TEXTURE_WRAP_S || PName == GL_TEXTURE_WRAP_T || PName == GL_TEXTURE_WRAP_R || PName == GL_TEXTURE_MIN_FILTER || PName == GL_TEXTURE_MAG_FILTER || PName == GL_TEXTURE_COMPARE_MODE || PName == GL_TEXTURE_COMPARE_FUNC) { SERIALISE_ELEMENT(GLenum, Param, (GLenum)param); ParamValue = (int32_t)Param; } else { SERIALISE_ELEMENT(int32_t, Param, param); ParamValue = Param; } if(m_State < WRITING) { GLResource res = GetResourceManager()->GetLiveResource(id); m_Real.glSamplerParameteri(res.name, PName, ParamValue); } return true; }
bool WrappedOpenGL::Serialise_glBindSamplers(GLuint first, GLsizei count, const GLuint *samplers) { SERIALISE_ELEMENT(uint32_t, First, first); SERIALISE_ELEMENT(int32_t, Count, count); GLuint *samps = NULL; if(m_State <= EXECUTING) samps = new GLuint[Count]; for(int32_t i = 0; i < Count; i++) { SERIALISE_ELEMENT(ResourceId, id, samplers && samplers[i] ? GetResourceManager()->GetID(SamplerRes(GetCtx(), samplers[i])) : ResourceId()); if(m_State <= EXECUTING) { if(id != ResourceId()) samps[i] = GetResourceManager()->GetLiveResource(id).name; else samps[i] = 0; } } if(m_State <= EXECUTING) { m_Real.glBindSamplers(First, Count, samps); delete[] samps; } return true; }
bool WrappedOpenGL::Serialise_glCreateSamplers(GLsizei n, GLuint *samplers) { SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(SamplerRes(GetCtx(), *samplers))); if(m_State == READING) { GLuint real = 0; m_Real.glCreateSamplers(1, &real); GLResource res = SamplerRes(GetCtx(), real); ResourceId live = m_ResourceManager->RegisterResource(res); GetResourceManager()->AddLiveResource(id, res); } return true; }
void WrappedOpenGL::glBindSampler(GLuint unit, GLuint sampler) { m_Real.glBindSampler(unit, sampler); if(m_State == WRITING_CAPFRAME) { SCOPED_SERIALISE_CONTEXT(BIND_SAMPLER); Serialise_glBindSampler(unit, sampler); m_ContextRecord->AddChunk(scope.Get()); GetResourceManager()->MarkResourceFrameReferenced(SamplerRes(GetCtx(), sampler), eFrameRef_Read); } }
bool WrappedOpenGL::Serialise_glSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) { SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(SamplerRes(GetCtx(), sampler))); SERIALISE_ELEMENT(GLenum, PName, pname); SERIALISE_ELEMENT(float, Param, param); if(m_State < WRITING) { GLResource res = GetResourceManager()->GetLiveResource(id); m_Real.glSamplerParameterf(res.name, PName, Param); } return true; }
void WrappedOpenGL::glDeleteSamplers(GLsizei n, const GLuint *ids) { for(GLsizei i = 0; i < n; i++) { GLResource res = SamplerRes(GetCtx(), ids[i]); if(GetResourceManager()->HasCurrentResource(res)) { if(GetResourceManager()->HasResourceRecord(res)) GetResourceManager()->GetResourceRecord(res)->Delete(GetResourceManager()); GetResourceManager()->UnregisterResource(res); } } m_Real.glDeleteSamplers(n, ids); }
void WrappedOpenGL::glBindSamplers(GLuint first, GLsizei count, const GLuint *samplers) { m_Real.glBindSamplers(first, count, samplers); if(m_State == WRITING_CAPFRAME) { SCOPED_SERIALISE_CONTEXT(BIND_SAMPLERS); Serialise_glBindSamplers(first, count, samplers); m_ContextRecord->AddChunk(scope.Get()); for(GLsizei i = 0; i < count; i++) if(samplers != NULL && samplers[i] != 0) GetResourceManager()->MarkResourceFrameReferenced(SamplerRes(GetCtx(), samplers[i]), eFrameRef_Read); } }
bool WrappedOpenGL::Serialise_glSamplerParameterIiv(GLuint sampler, GLenum pname, const GLint *params) { SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(SamplerRes(GetCtx(), sampler))); SERIALISE_ELEMENT(GLenum, PName, pname); const size_t nParams = (PName == eGL_TEXTURE_BORDER_COLOR ? 4U : 1U); SERIALISE_ELEMENT_ARR(int32_t, Params, params, nParams); if(m_State < WRITING) { GLResource res = GetResourceManager()->GetLiveResource(id); m_Real.glSamplerParameterIiv(res.name, PName, Params); } delete[] Params; return true; }
bool WrappedOpenGL::Serialise_glBindSampler(GLuint unit, GLuint sampler) { SERIALISE_ELEMENT(uint32_t, Unit, unit); SERIALISE_ELEMENT(ResourceId, id, sampler ? GetResourceManager()->GetID(SamplerRes(GetCtx(), sampler)) : ResourceId()); if(m_State < WRITING) { if(id == ResourceId()) { m_Real.glBindSampler(Unit, 0); } else { GLResource res = GetResourceManager()->GetLiveResource(id); m_Real.glBindSampler(Unit, res.name); } } return true; }
void GLRenderState::Serialise(LogState state, void *ctx, WrappedOpenGL *gl) { GLResourceManager *rm = gl->GetResourceManager(); // TODO check GL_MAX_* m_pSerialiser->Serialise<eEnabled_Count>("GL_ENABLED", Enabled); for(size_t i=0; i < ARRAY_COUNT(Tex2D); i++) { ResourceId ID = ResourceId(); if(state >= WRITING) ID = rm->GetID(TextureRes(ctx, Tex2D[i])); m_pSerialiser->Serialise("GL_TEXTURE_BINDING_2D", ID); if(state < WRITING && ID != ResourceId()) Tex2D[i] = rm->GetLiveResource(ID).name; } for(size_t i=0; i < ARRAY_COUNT(Samplers); i++) { ResourceId ID = ResourceId(); if(state >= WRITING) ID = rm->GetID(SamplerRes(ctx, Samplers[i])); m_pSerialiser->Serialise("GL_SAMPLER_BINDING", ID); if(state < WRITING && ID != ResourceId()) Samplers[i] = rm->GetLiveResource(ID).name; } m_pSerialiser->Serialise("GL_ACTIVE_TEXTURE", ActiveTexture); { ResourceId ID = ResourceId(); if(state >= WRITING) ID = rm->GetID(VertexArrayRes(ctx, VAO)); m_pSerialiser->Serialise("GL_VERTEX_ARRAY_BINDING", ID); if(state < WRITING && ID != ResourceId()) VAO = rm->GetLiveResource(ID).name; if(VAO == 0) VAO = gl->GetFakeVAO(); } { ResourceId ID = ResourceId(); if(state >= WRITING) ID = rm->GetID(FeedbackRes(ctx, FeedbackObj)); m_pSerialiser->Serialise("GL_TRANSFORM_FEEDBACK_BINDING", ID); if(state < WRITING && ID != ResourceId()) FeedbackObj = rm->GetLiveResource(ID).name; } for(size_t i=0; i < ARRAY_COUNT(GenericVertexAttribs); i++) { m_pSerialiser->Serialise<4>("GL_CURRENT_VERTEX_ATTRIB", &GenericVertexAttribs[i].x); } m_pSerialiser->Serialise("GL_POINT_FADE_THRESHOLD_SIZE", PointFadeThresholdSize); m_pSerialiser->Serialise("GL_POINT_SPRITE_COORD_ORIGIN", PointSpriteOrigin); m_pSerialiser->Serialise("GL_LINE_WIDTH", LineWidth); m_pSerialiser->Serialise("GL_POINT_SIZE", PointSize); m_pSerialiser->Serialise("GL_PRIMITIVE_RESTART_INDEX", PrimitiveRestartIndex); m_pSerialiser->Serialise("GL_CLIP_ORIGIN", ClipOrigin); m_pSerialiser->Serialise("GL_CLIP_DEPTH_MODE", ClipDepth); m_pSerialiser->Serialise("GL_PROVOKING_VERTEX", ProvokingVertex); for(size_t i=0; i < ARRAY_COUNT(BufferBindings); i++) { ResourceId ID = ResourceId(); if(state >= WRITING) ID = rm->GetID(BufferRes(ctx, BufferBindings[i])); m_pSerialiser->Serialise("GL_BUFFER_BINDING", ID); if(state < WRITING && ID != ResourceId()) BufferBindings[i] = rm->GetLiveResource(ID).name; } { ResourceId ID = ResourceId(); if(state >= WRITING) ID = rm->GetID(ProgramRes(ctx, Program)); m_pSerialiser->Serialise("GL_CURRENT_PROGRAM", ID); if(state < WRITING && ID != ResourceId()) Program = rm->GetLiveResource(ID).name; } { ResourceId ID = ResourceId(); if(state >= WRITING) ID = rm->GetID(ProgramPipeRes(ctx, Pipeline)); m_pSerialiser->Serialise("GL_PROGRAM_PIPELINE_BINDING", ID); if(state < WRITING && ID != ResourceId()) Pipeline = rm->GetLiveResource(ID).name; } for(size_t s=0; s < ARRAY_COUNT(Subroutines); s++) { m_pSerialiser->Serialise("GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS", Subroutines[s].numSubroutines); m_pSerialiser->Serialise<128>("GL_SUBROUTINE_UNIFORMS", Subroutines[s].Values); } { ResourceId ID = ResourceId(); if(state >= WRITING) ID = rm->GetID(FramebufferRes(ctx, DrawFBO)); m_pSerialiser->Serialise("GL_DRAW_FRAMEBUFFER_BINDING", ID); if(state < WRITING && ID != ResourceId()) DrawFBO = rm->GetLiveResource(ID).name; if(DrawFBO == 0) DrawFBO = gl->GetFakeBBFBO(); } { ResourceId ID = ResourceId(); if(state >= WRITING) ID = rm->GetID(FramebufferRes(ctx, ReadFBO)); m_pSerialiser->Serialise("GL_READ_FRAMEBUFFER_BINDING", ID); if(state < WRITING && ID != ResourceId()) ReadFBO = rm->GetLiveResource(ID).name; if(ReadFBO == 0) ReadFBO = gl->GetFakeBBFBO(); } struct { IdxRangeBuffer *bufs; int count; } idxBufs[] = { { AtomicCounter, ARRAY_COUNT(AtomicCounter), }, { ShaderStorage, ARRAY_COUNT(ShaderStorage), }, { TransformFeedback, ARRAY_COUNT(TransformFeedback), }, { UniformBinding, ARRAY_COUNT(UniformBinding), }, }; for(size_t b=0; b < ARRAY_COUNT(idxBufs); b++) { for(int i=0; i < idxBufs[b].count; i++) { ResourceId ID = ResourceId(); if(state >= WRITING) ID = rm->GetID(BufferRes(ctx, idxBufs[b].bufs[i].name)); m_pSerialiser->Serialise("BUFFER_BINDING", ID); if(state < WRITING && ID != ResourceId()) idxBufs[b].bufs[i].name = rm->GetLiveResource(ID).name; m_pSerialiser->Serialise("BUFFER_START", idxBufs[b].bufs[i].start); m_pSerialiser->Serialise("BUFFER_SIZE", idxBufs[b].bufs[i].size); } } for(size_t i=0; i < ARRAY_COUNT(Blends); i++) { m_pSerialiser->Serialise("GL_BLEND_EQUATION_RGB", Blends[i].EquationRGB); m_pSerialiser->Serialise("GL_BLEND_EQUATION_ALPHA", Blends[i].EquationAlpha); m_pSerialiser->Serialise("GL_BLEND_SRC_RGB", Blends[i].SourceRGB); m_pSerialiser->Serialise("GL_BLEND_SRC_ALPHA", Blends[i].SourceAlpha); m_pSerialiser->Serialise("GL_BLEND_DST_RGB", Blends[i].DestinationRGB); m_pSerialiser->Serialise("GL_BLEND_DST_ALPHA", Blends[i].DestinationAlpha); m_pSerialiser->Serialise("GL_BLEND", Blends[i].Enabled); } m_pSerialiser->Serialise<4>("GL_BLEND_COLOR", BlendColor); for(size_t i=0; i < ARRAY_COUNT(Viewports); i++) { m_pSerialiser->Serialise("GL_VIEWPORT.x", Viewports[i].x); m_pSerialiser->Serialise("GL_VIEWPORT.y", Viewports[i].y); m_pSerialiser->Serialise("GL_VIEWPORT.w", Viewports[i].width); m_pSerialiser->Serialise("GL_VIEWPORT.h", Viewports[i].height); } for(size_t i=0; i < ARRAY_COUNT(Scissors); i++) { m_pSerialiser->Serialise("GL_SCISSOR.x", Scissors[i].x); m_pSerialiser->Serialise("GL_SCISSOR.y", Scissors[i].y); m_pSerialiser->Serialise("GL_SCISSOR.w", Scissors[i].width); m_pSerialiser->Serialise("GL_SCISSOR.h", Scissors[i].height); m_pSerialiser->Serialise("GL_SCISSOR.enabled", Scissors[i].enabled); } m_pSerialiser->Serialise<8>("GL_DRAW_BUFFERS", DrawBuffers); m_pSerialiser->Serialise("GL_READ_BUFFER", ReadBuffer); m_pSerialiser->Serialise("GL_FRAGMENT_SHADER_DERIVATIVE_HINT", Hints.Derivatives); m_pSerialiser->Serialise("GL_LINE_SMOOTH_HINT", Hints.LineSmooth); m_pSerialiser->Serialise("GL_POLYGON_SMOOTH_HINT", Hints.PolySmooth); m_pSerialiser->Serialise("GL_TEXTURE_COMPRESSION_HINT", Hints.TexCompression); m_pSerialiser->Serialise("GL_DEPTH_WRITEMASK", DepthWriteMask); m_pSerialiser->Serialise("GL_DEPTH_CLEAR_VALUE", DepthClearValue); m_pSerialiser->Serialise("GL_DEPTH_FUNC", DepthFunc); for(size_t i=0; i < ARRAY_COUNT(DepthRanges); i++) { m_pSerialiser->Serialise("GL_DEPTH_RANGE.near", DepthRanges[i].nearZ); m_pSerialiser->Serialise("GL_DEPTH_RANGE.far", DepthRanges[i].farZ); } { m_pSerialiser->Serialise("GL_DEPTH_BOUNDS_EXT.near", DepthBounds.nearZ); m_pSerialiser->Serialise("GL_DEPTH_BOUNDS_EXT.far", DepthBounds.farZ); } { m_pSerialiser->Serialise("GL_STENCIL_FUNC", StencilFront.func); m_pSerialiser->Serialise("GL_STENCIL_BACK_FUNC", StencilBack.func); m_pSerialiser->Serialise("GL_STENCIL_REF", StencilFront.ref); m_pSerialiser->Serialise("GL_STENCIL_BACK_REF", StencilBack.ref); m_pSerialiser->Serialise("GL_STENCIL_VALUE_MASK", StencilFront.valuemask); m_pSerialiser->Serialise("GL_STENCIL_BACK_VALUE_MASK", StencilBack.valuemask); m_pSerialiser->Serialise("GL_STENCIL_WRITEMASK", StencilFront.writemask); m_pSerialiser->Serialise("GL_STENCIL_BACK_WRITEMASK", StencilBack.writemask); m_pSerialiser->Serialise("GL_STENCIL_FAIL", StencilFront.stencilFail); m_pSerialiser->Serialise("GL_STENCIL_BACK_FAIL", StencilBack.stencilFail); m_pSerialiser->Serialise("GL_STENCIL_PASS_DEPTH_FAIL", StencilFront.depthFail); m_pSerialiser->Serialise("GL_STENCIL_BACK_PASS_DEPTH_FAIL", StencilBack.depthFail); m_pSerialiser->Serialise("GL_STENCIL_PASS_DEPTH_PASS", StencilFront.pass); m_pSerialiser->Serialise("GL_STENCIL_BACK_PASS_DEPTH_PASS", StencilBack.pass); } m_pSerialiser->Serialise("GL_STENCIL_CLEAR_VALUE", StencilClearValue); for(size_t i=0; i < ARRAY_COUNT(ColorMasks); i++) m_pSerialiser->Serialise<4>("GL_COLOR_WRITEMASK", &ColorMasks[i].red); m_pSerialiser->Serialise<2>("GL_SAMPLE_MASK_VALUE", &SampleMask[0]); m_pSerialiser->Serialise("GL_SAMPLE_COVERAGE_VALUE", SampleCoverage); m_pSerialiser->Serialise("GL_SAMPLE_COVERAGE_INVERT", SampleCoverageInvert); m_pSerialiser->Serialise("GL_MIN_SAMPLE_SHADING", MinSampleShading); m_pSerialiser->Serialise("GL_RASTER_SAMPLES_EXT", RasterSamples); m_pSerialiser->Serialise("GL_RASTER_FIXED_SAMPLE_LOCATIONS_EXT", RasterFixed); m_pSerialiser->Serialise("GL_LOGIC_OP_MODE", LogicOp); m_pSerialiser->Serialise<4>("GL_COLOR_CLEAR_VALUE", &ColorClearValue.red); { m_pSerialiser->Serialise("GL_PATCH_VERTICES", PatchParams.numVerts); m_pSerialiser->Serialise<2>("GL_PATCH_DEFAULT_INNER_LEVEL", &PatchParams.defaultInnerLevel[0]); m_pSerialiser->Serialise<4>("GL_PATCH_DEFAULT_OUTER_LEVEL", &PatchParams.defaultOuterLevel[0]); } m_pSerialiser->Serialise("GL_POLYGON_MODE", PolygonMode); m_pSerialiser->Serialise("GL_POLYGON_OFFSET_FACTOR", PolygonOffset[0]); m_pSerialiser->Serialise("GL_POLYGON_OFFSET_UNITS", PolygonOffset[1]); m_pSerialiser->Serialise("GL_POLYGON_OFFSET_CLAMP_EXT", PolygonOffset[2]); m_pSerialiser->Serialise("GL_FRONT_FACE", FrontFace); m_pSerialiser->Serialise("GL_CULL_FACE_MODE", CullFace); }
bool WrappedOpenGL::Serialise_glObjectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label) { ResourceId liveid; bool extvariant = false; string Label; if(m_State >= WRITING) { if(length == 0) Label = ""; else Label = string(label, label + (length > 0 ? length : strlen(label))); switch(identifier) { case eGL_TEXTURE: liveid = GetResourceManager()->GetID(TextureRes(GetCtx(), name)); break; case eGL_BUFFER_OBJECT_EXT: extvariant = true; case eGL_BUFFER: liveid = GetResourceManager()->GetID(BufferRes(GetCtx(), name)); break; case eGL_PROGRAM_OBJECT_EXT: extvariant = true; case eGL_PROGRAM: liveid = GetResourceManager()->GetID(ProgramRes(GetCtx(), name)); break; case eGL_PROGRAM_PIPELINE_OBJECT_EXT: extvariant = true; case eGL_PROGRAM_PIPELINE: liveid = GetResourceManager()->GetID(ProgramPipeRes(GetCtx(), name)); break; case eGL_VERTEX_ARRAY_OBJECT_EXT: extvariant = true; case eGL_VERTEX_ARRAY: liveid = GetResourceManager()->GetID(VertexArrayRes(GetCtx(), name)); break; case eGL_SHADER_OBJECT_EXT: extvariant = true; case eGL_SHADER: liveid = GetResourceManager()->GetID(ShaderRes(GetCtx(), name)); break; case eGL_QUERY_OBJECT_EXT: extvariant = true; case eGL_QUERY: liveid = GetResourceManager()->GetID(QueryRes(GetCtx(), name)); break; case eGL_TRANSFORM_FEEDBACK: liveid = GetResourceManager()->GetID(FeedbackRes(GetCtx(), name)); break; case eGL_SAMPLER: liveid = GetResourceManager()->GetID(SamplerRes(GetCtx(), name)); break; case eGL_RENDERBUFFER: liveid = GetResourceManager()->GetID(RenderbufferRes(GetCtx(), name)); break; case eGL_FRAMEBUFFER: liveid = GetResourceManager()->GetID(FramebufferRes(GetCtx(), name)); break; default: RDCERR("Unhandled namespace in glObjectLabel"); } } SERIALISE_ELEMENT(GLenum, Identifier, identifier); SERIALISE_ELEMENT(ResourceId, id, liveid); SERIALISE_ELEMENT(uint32_t, Length, length); SERIALISE_ELEMENT(bool, HasLabel, label != NULL); m_pSerialiser->SerialiseString("label", Label); if(m_State == READING && GetResourceManager()->HasLiveResource(id)) { GLResource res = GetResourceManager()->GetLiveResource(id); if(extvariant && m_Real.glLabelObjectEXT) m_Real.glLabelObjectEXT(Identifier, res.name, Length, HasLabel ? Label.c_str() : NULL); else m_Real.glObjectLabel(Identifier, res.name, Length, HasLabel ? Label.c_str() : NULL); } return true; }
bool WrappedOpenGL::Serialise_glObjectLabel(SerialiserType &ser, GLenum identifier, GLuint name, GLsizei length, const GLchar *label) { GLResource Resource; std::string Label; if(ser.IsWriting()) { // we share implementations between KHR_debug and EXT_debug_label, however KHR_debug follows the // pattern elsewhere (e.g. in glShaderSource) of a length of -1 meaning indeterminate // NULL-terminated length, but EXT_debug_label takes length of 0 to mean that. GLsizei realLength = length; if(gl_CurChunk == GLChunk::glLabelObjectEXT && length == 0) realLength = -1; // if length is negative (after above twiddling), it's taken from strlen and the label must be // NULL-terminated if(realLength < 0) realLength = label ? (GLsizei)strlen(label) : 0; if(realLength == 0 || label == NULL) Label = ""; else Label = std::string(label, label + realLength); switch(identifier) { case eGL_TEXTURE: Resource = TextureRes(GetCtx(), name); break; case eGL_BUFFER_OBJECT_EXT: case eGL_BUFFER: Resource = BufferRes(GetCtx(), name); break; case eGL_PROGRAM_OBJECT_EXT: case eGL_PROGRAM: Resource = ProgramRes(GetCtx(), name); break; case eGL_PROGRAM_PIPELINE_OBJECT_EXT: case eGL_PROGRAM_PIPELINE: Resource = ProgramPipeRes(GetCtx(), name); break; case eGL_VERTEX_ARRAY_OBJECT_EXT: case eGL_VERTEX_ARRAY: Resource = VertexArrayRes(GetCtx(), name); break; case eGL_SHADER_OBJECT_EXT: case eGL_SHADER: Resource = ShaderRes(GetCtx(), name); break; case eGL_QUERY_OBJECT_EXT: case eGL_QUERY: Resource = QueryRes(GetCtx(), name); break; case eGL_TRANSFORM_FEEDBACK: Resource = FeedbackRes(GetCtx(), name); break; case eGL_SAMPLER: Resource = SamplerRes(GetCtx(), name); break; case eGL_RENDERBUFFER: Resource = RenderbufferRes(GetCtx(), name); break; case eGL_FRAMEBUFFER: Resource = FramebufferRes(GetCtx(), name); break; default: RDCERR("Unhandled namespace in glObjectLabel"); } } SERIALISE_ELEMENT(Resource); SERIALISE_ELEMENT(length); SERIALISE_ELEMENT(Label); SERIALISE_CHECK_READ_ERRORS(); if(IsReplayingAndReading() && Resource.name) { ResourceId origId = GetResourceManager()->GetOriginalID(GetResourceManager()->GetID(Resource)); GetResourceManager()->SetName(origId, Label); ResourceDescription &descr = GetReplay()->GetResourceDesc(origId); descr.SetCustomName(Label); AddResourceCurChunk(descr); } return true; }