void WrappedOpenGL::glCreateProgramPipelines(GLsizei n, GLuint *pipelines)
{
  m_Real.glCreateProgramPipelines(n, pipelines);

  for(GLsizei i = 0; i < n; i++)
  {
    GLResource res = ProgramPipeRes(GetCtx(), pipelines[i]);
    ResourceId id = GetResourceManager()->RegisterResource(res);

    if(m_State >= WRITING)
    {
      Chunk *chunk = NULL;

      {
        SCOPED_SERIALISE_CONTEXT(CREATE_PROGRAMPIPE);
        Serialise_glCreateProgramPipelines(1, pipelines + i);

        chunk = scope.Get();
      }

      GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id);
      RDCASSERT(record);

      record->AddChunk(chunk);
    }
    else
    {
      GetResourceManager()->AddLiveResource(id, res);
    }
  }
}
Example #2
0
bool WrappedOpenGL::Serialise_glCreateProgramPipelines(GLsizei n, GLuint* pipelines)
{
	SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ProgramPipeRes(GetCtx(), *pipelines)));

	if(m_State == READING)
	{
		GLuint real = 0;
		m_Real.glCreateProgramPipelines(1, &real);
		
		GLResource res = ProgramPipeRes(GetCtx(), real);

		ResourceId live = m_ResourceManager->RegisterResource(res);
		GetResourceManager()->AddLiveResource(id, res);
	}

	return true;
}
Example #3
0
bool WrappedOpenGL::Serialise_glUseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program)
{
	SERIALISE_ELEMENT(ResourceId, pipe, GetResourceManager()->GetID(ProgramPipeRes(GetCtx(), pipeline)));
	SERIALISE_ELEMENT(uint32_t, Stages, stages);
	SERIALISE_ELEMENT(ResourceId, prog, (program ? GetResourceManager()->GetID(ProgramRes(GetCtx(), program)) : ResourceId()));

	if(m_State < WRITING)
	{
		if(prog != ResourceId())
		{
			ResourceId livePipeId = GetResourceManager()->GetLiveID(pipe);
			ResourceId liveProgId = GetResourceManager()->GetLiveID(prog);

			PipelineData &pipeDetails = m_Pipelines[livePipeId];
			ProgramData &progDetails = m_Programs[liveProgId];

			for(size_t s=0; s < 6; s++)
			{
				if(Stages & ShaderBit(s))
				{
					for(size_t sh=0; sh < progDetails.shaders.size(); sh++)
					{
						if(m_Shaders[ progDetails.shaders[sh] ].type == ShaderEnum(s))
						{
							pipeDetails.stagePrograms[s] = liveProgId;
							pipeDetails.stageShaders[s] = progDetails.shaders[sh];
							break;
						}
					}
				}
			}

			m_Real.glUseProgramStages(GetResourceManager()->GetLiveResource(pipe).name,
																Stages,
																GetResourceManager()->GetLiveResource(prog).name);
		}
		else
		{
			ResourceId livePipeId = GetResourceManager()->GetLiveID(pipe);
			PipelineData &pipeDetails = m_Pipelines[livePipeId];

			for(size_t s=0; s < 6; s++)
			{
				if(Stages & ShaderBit(s))
				{
					pipeDetails.stagePrograms[s] = ResourceId();
					pipeDetails.stageShaders[s] = ResourceId();
				}
			}

			m_Real.glUseProgramStages(GetResourceManager()->GetLiveResource(pipe).name,
																Stages,
																0);
		}
	}

	return true;
}
void WrappedOpenGL::glDeleteProgramPipelines(GLsizei n, const GLuint *pipelines)
{
  for(GLsizei i = 0; i < n; i++)
  {
    GLResource res = ProgramPipeRes(GetCtx(), pipelines[i]);
    if(GetResourceManager()->HasCurrentResource(res))
    {
      if(GetResourceManager()->HasResourceRecord(res))
        GetResourceManager()->GetResourceRecord(res)->Delete(GetResourceManager());
      GetResourceManager()->UnregisterResource(res);
    }
  }

  m_Real.glDeleteProgramPipelines(n, pipelines);
}
void WrappedOpenGL::glBindProgramPipeline(GLuint pipeline)
{
  m_Real.glBindProgramPipeline(pipeline);

  GetCtxData().m_ProgramPipeline = pipeline;

  if(m_State == WRITING_CAPFRAME)
  {
    SCOPED_SERIALISE_CONTEXT(BIND_PROGRAMPIPE);
    Serialise_glBindProgramPipeline(pipeline);

    m_ContextRecord->AddChunk(scope.Get());
    GetResourceManager()->MarkResourceFrameReferenced(ProgramPipeRes(GetCtx(), pipeline),
                                                      eFrameRef_Read);
  }
}
Example #6
0
bool WrappedOpenGL::Serialise_glBindProgramPipeline(GLuint pipeline)
{
	SERIALISE_ELEMENT(ResourceId, id, (pipeline ? GetResourceManager()->GetID(ProgramPipeRes(GetCtx(), pipeline)) : ResourceId()));

	if(m_State <= EXECUTING)
	{
		if(id == ResourceId())
		{
			m_Real.glBindProgramPipeline(0);
		}
		else
		{
			GLuint live = GetResourceManager()->GetLiveResource(id).name;
			m_Real.glBindProgramPipeline(live);
		}
	}

	return true;
}
Example #7
0
void WrappedOpenGL::glUseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program)
{
	m_Real.glUseProgramStages(pipeline, stages, program);

	if(m_State > WRITING)
	{
		SCOPED_SERIALISE_CONTEXT(USE_PROGRAMSTAGES);
		Serialise_glUseProgramStages(pipeline, stages, program);
		
		GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ProgramPipeRes(GetCtx(), pipeline));
		RDCASSERT(record);
		record->AddChunk(scope.Get());

		if(program)
		{
			GLResourceRecord *progrecord = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), program));
			RDCASSERT(progrecord);
			record->AddParent(progrecord);
		}
	}
}
Example #8
0
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);
}
void WrappedOpenGL::glUseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program)
{
  m_Real.glUseProgramStages(pipeline, stages, program);

  if(m_State > WRITING)
  {
    SCOPED_SERIALISE_CONTEXT(USE_PROGRAMSTAGES);
    Serialise_glUseProgramStages(pipeline, stages, program);

    GLResourceRecord *record =
        GetResourceManager()->GetResourceRecord(ProgramPipeRes(GetCtx(), pipeline));
    RDCASSERT(record);

    Chunk *chunk = scope.Get();

    if(m_State == WRITING_CAPFRAME)
    {
      m_ContextRecord->AddChunk(chunk);
    }
    else
    {
      // USE_PROGRAMSTAGES is one of the few kinds of chunk that are
      // recorded to pipeline records, so we can probably find previous
      // uses (if it's been constantly rebound instead of once at init
      // time) that can be popped as redundant.
      // We do have to be careful though to make sure we only remove
      // redundant calls, not other different USE_PROGRAMSTAGES calls!
      struct FilterChunkClass
      {
        FilterChunkClass(uint32_t s) : stages(s) {}
        uint32_t stages;

        // this is kind of a hack, but it would be really awkward
        // to make a general solution just for this one case, and
        // we also can't really afford to drop it entirely.
        // we search for the marker serialised above, skip over the
        // pipeline id (as it will be the same in all chunks in this
        // record), and check if the Stages bitfield afterwards is
        // the same - if so we remove that chunk as replaced by
        // this one
        bool operator()(Chunk *c) const
        {
          if(c->GetChunkType() != USE_PROGRAMSTAGES)
            return false;

          byte *b = c->GetData();
          byte *end = b + c->GetLength();

          // 'fast' path, rather than searching byte-by-byte from
          // the start to be safe, check the exact difference it should
          // always be first.
          if(*(uint64_t *)(b + 6) == marker_glUseProgramStages_hack)
            b += 6;

          while(b + sizeof(uint64_t) < end)
          {
            uint64_t *marker = (uint64_t *)b;
            if(*marker == marker_glUseProgramStages_hack)
            {
              // increment to point to pipeline id
              marker++;
              // increment to point to stages field
              marker++;

              // now compare
              uint32_t *chunkStages = (uint32_t *)marker;

              if(*chunkStages == stages)
                return true;
              return false;
            }

            b++;
          }
          RDCERR(
              "Didn't find marker value! This should not happen, check "
              "Serialise_glUseProgramStages serialisation");
          return false;
        }
      };
      record->FilterChunks(FilterChunkClass(stages));

      record->AddChunk(chunk);
    }

    if(program)
    {
      GLResourceRecord *progrecord =
          GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), program));
      RDCASSERT(progrecord);
      record->AddParent(progrecord);
    }
  }
  else
  {
    if(program)
    {
      ResourceId pipeID = GetResourceManager()->GetID(ProgramPipeRes(GetCtx(), pipeline));
      ResourceId progID = GetResourceManager()->GetID(ProgramRes(GetCtx(), program));

      PipelineData &pipeDetails = m_Pipelines[pipeID];
      ProgramData &progDetails = m_Programs[progID];

      for(size_t s = 0; s < 6; s++)
      {
        if(stages & ShaderBit(s))
        {
          for(size_t sh = 0; sh < progDetails.shaders.size(); sh++)
          {
            if(m_Shaders[progDetails.shaders[sh]].type == ShaderEnum(s))
            {
              pipeDetails.stagePrograms[s] = progID;
              pipeDetails.stageShaders[s] = progDetails.shaders[sh];
              break;
            }
          }
        }
      }
    }
    else
    {
      ResourceId pipeID = GetResourceManager()->GetID(ProgramPipeRes(GetCtx(), pipeline));
      PipelineData &pipeDetails = m_Pipelines[pipeID];

      for(size_t s = 0; s < 6; s++)
      {
        if(stages & ShaderBit(s))
        {
          pipeDetails.stagePrograms[s] = ResourceId();
          pipeDetails.stageShaders[s] = ResourceId();
        }
      }
    }
  }
}
Example #10
0
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;
}
Example #11
0
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;
}