コード例 #1
0
void WrappedOpenGL::glCopyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ,
												               GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ,
												               GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth)
{
	m_Real.glCopyImageSubData(srcName, srcTarget, srcLevel, srcX, srcY, srcZ,
												    dstName, dstTarget, dstLevel, dstX, dstY, dstZ,
												    srcWidth, srcHeight, srcDepth);
	
	if(m_State >= WRITING)
	{
		GLResourceRecord *srcrecord = GetResourceManager()->GetResourceRecord(TextureRes(srcName));
		GLResourceRecord *dstrecord = GetResourceManager()->GetResourceRecord(TextureRes(dstName));
		RDCASSERT(srcrecord && dstrecord);

		SCOPED_SERIALISE_CONTEXT(COPY_SUBIMAGE);
		Serialise_glCopyImageSubData(srcName, srcTarget, srcLevel, srcX, srcY, srcZ,
												         dstName, dstTarget, dstLevel, dstX, dstY, dstZ,
												         srcWidth, srcHeight, srcDepth);

		Chunk *chunk = scope.Get();

		if(m_State == WRITING_CAPFRAME)
		{
			m_ContextRecord->AddChunk(chunk);
		}
		else
		{
			dstrecord->AddChunk(chunk);
			dstrecord->AddParent(srcrecord);
		}
	}
}
コード例 #2
0
void WrappedOpenGL::glAttachShader(GLuint program, GLuint shader)
{
  m_Real.glAttachShader(program, shader);

  if(m_State >= WRITING && program != 0 && shader != 0)
  {
    GLResourceRecord *progRecord =
        GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), program));
    GLResourceRecord *shadRecord =
        GetResourceManager()->GetResourceRecord(ShaderRes(GetCtx(), shader));
    RDCASSERT(progRecord && shadRecord);
    if(progRecord && shadRecord)
    {
      SCOPED_SERIALISE_CONTEXT(ATTACHSHADER);
      Serialise_glAttachShader(program, shader);

      progRecord->AddParent(shadRecord);
      progRecord->AddChunk(scope.Get());
    }
  }
  else
  {
    ResourceId progid = GetResourceManager()->GetID(ProgramRes(GetCtx(), program));
    ResourceId shadid = GetResourceManager()->GetID(ShaderRes(GetCtx(), shader));
    m_Programs[progid].shaders.push_back(shadid);
  }
}
コード例 #3
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);
		}
	}
}
コード例 #4
0
void WrappedOpenGL::glTextureView(GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers)
{
	m_Real.glTextureView(texture, target, origtexture, internalformat, minlevel, numlevels, minlayer, numlayers);
	
	if(m_State >= WRITING)
	{
		GLResourceRecord *record = GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture));
		GLResourceRecord *origrecord = GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), origtexture));
		RDCASSERT(record && origrecord);

		SCOPED_SERIALISE_CONTEXT(TEXTURE_VIEW);
		Serialise_glTextureView(texture, target, origtexture, internalformat, minlevel, numlevels, minlayer, numlayers);

		record->AddChunk(scope.Get());
		record->AddParent(origrecord);

		// illegal to re-type textures
		if(record->datatype == eGL_UNKNOWN_ENUM)
			record->datatype = target;
		else
			RDCASSERT(record->datatype == target);
	}
}
コード例 #5
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);

    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();
        }
      }
    }
  }
}