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);
  }
}
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);
    }
  }
}
void WrappedOpenGL::glGenFramebuffers(GLsizei n, GLuint *framebuffers)
{
	m_Real.glGenFramebuffers(n, framebuffers);

	for(GLsizei i=0; i < n; i++)
	{
		GLResource res = FramebufferRes(GetCtx(), framebuffers[i]);
		ResourceId id = GetResourceManager()->RegisterResource(res);
		
		if(m_State >= WRITING)
		{
			Chunk *chunk = NULL;

			{
				SCOPED_SERIALISE_CONTEXT(GEN_FRAMEBUFFERS);
				Serialise_glGenFramebuffers(1, framebuffers+i);

				chunk = scope.Get();
			}

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

			record->AddChunk(chunk);
		}
		else
		{
			GetResourceManager()->AddLiveResource(id, res);
		}
	}
}
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);
		}
	}
}
void WrappedOpenGL::glGenTextures(GLsizei n, GLuint* textures)
{
	m_Real.glGenTextures(n, textures);

	for(GLsizei i=0; i < n; i++)
	{
		GLResource res = TextureRes(textures[i]);
		ResourceId id = GetResourceManager()->RegisterResource(res);

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

			{
				SCOPED_SERIALISE_CONTEXT(GEN_TEXTURE);
				Serialise_glGenTextures(1, textures+i);

				chunk = scope.Get();
			}

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

			record->AddChunk(chunk);
		}
		else
		{
			GetResourceManager()->AddLiveResource(id, res);
			m_Textures[id].resource = res;
			m_Textures[id].curType = eGL_UNKNOWN_ENUM;
		}
	}
}
void WrappedOpenGL::glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer)
{
	m_Real.glFramebufferTextureLayer(target, attachment, texture, level, layer);
	
	if(m_State >= WRITING)
	{
		GLResourceRecord *record = m_DeviceRecord;

		if(target == eGL_DRAW_FRAMEBUFFER || target == eGL_FRAMEBUFFER)
		{
			if(m_DrawFramebufferRecord) record = m_DrawFramebufferRecord;
		}
		else
		{
			if(m_ReadFramebufferRecord) record = m_ReadFramebufferRecord;
		}

		SCOPED_SERIALISE_CONTEXT(FRAMEBUFFER_TEXLAYER);
		Serialise_glNamedFramebufferTextureLayerEXT(GetResourceManager()->GetCurrentResource(record->GetResourceID()).name,
																					 attachment, texture, level, layer);
		
		if(m_State == WRITING_IDLE)
			record->AddChunk(scope.Get());
		else
			m_ContextRecord->AddChunk(scope.Get());
	}
}
void WrappedOpenGL::glLinkProgram(GLuint program)
{
  m_Real.glLinkProgram(program);

  if(m_State >= WRITING)
  {
    GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), program));
    RDCASSERT(record);
    {
      SCOPED_SERIALISE_CONTEXT(LINKPROGRAM);
      Serialise_glLinkProgram(program);

      record->AddChunk(scope.Get());
    }
  }
  else
  {
    ResourceId progid = GetResourceManager()->GetID(ProgramRes(GetCtx(), program));

    ProgramData &progDetails = m_Programs[progid];

    progDetails.linked = true;

    for(size_t s = 0; s < 6; s++)
    {
      for(size_t sh = 0; sh < progDetails.shaders.size(); sh++)
      {
        if(m_Shaders[progDetails.shaders[sh]].type == ShaderEnum(s))
          progDetails.stageShaders[s] = progDetails.shaders[sh];
      }
    }
  }
}
void WrappedOpenGL::glShaderSource(GLuint shader, GLsizei count, const GLchar *const *string,
                                   const GLint *length)
{
  m_Real.glShaderSource(shader, count, string, length);

  if(m_State >= WRITING)
  {
    GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ShaderRes(GetCtx(), shader));
    RDCASSERT(record);
    {
      SCOPED_SERIALISE_CONTEXT(SHADERSOURCE);
      Serialise_glShaderSource(shader, count, string, length);

      record->AddChunk(scope.Get());
    }
  }
  else
  {
    ResourceId id = GetResourceManager()->GetID(ShaderRes(GetCtx(), shader));
    m_Shaders[id].sources.clear();
    m_Shaders[id].sources.reserve(count);

    for(GLsizei i = 0; i < count; i++)
      m_Shaders[id].sources.push_back(string[i]);
  }
}
GLuint WrappedOpenGL::glCreateShader(GLenum type)
{
  GLuint real = m_Real.glCreateShader(type);

  GLResource res = ShaderRes(GetCtx(), real);
  ResourceId id = GetResourceManager()->RegisterResource(res);

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

    {
      SCOPED_SERIALISE_CONTEXT(CREATE_SHADER);
      Serialise_glCreateShader(real, type);

      chunk = scope.Get();
    }

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

    record->AddChunk(chunk);
  }
  else
  {
    GetResourceManager()->AddLiveResource(id, res);

    m_Shaders[id].type = type;
  }

  return real;
}
GLuint WrappedOpenGL::glCreateProgram()
{
	GLuint real = m_Real.glCreateProgram();
	
	GLResource res = ProgramRes(GetCtx(), real);
	ResourceId id = GetResourceManager()->RegisterResource(res);
		
	if(m_State >= WRITING)
	{
		Chunk *chunk = NULL;

		{
			SCOPED_SERIALISE_CONTEXT(CREATE_PROGRAM);
			Serialise_glCreateProgram(real);

			chunk = scope.Get();
		}

		GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id);
		RDCASSERT(record);
		
		// we always want to mark programs as dirty so we can serialise their
		// locations as initial state (and form a remapping table)
		GetResourceManager()->MarkDirtyResource(id);

		record->AddChunk(chunk);
	}
	else
	{
		GetResourceManager()->AddLiveResource(id, res);
	}

	return real;
}
Exemple #11
0
void WrappedOpenGL::glGenQueries(GLsizei count, GLuint *ids)
{
	m_Real.glGenSamplers(count, ids);

	for(GLsizei i=0; i < count; i++)
	{
		GLResource res = QueryRes(ids[i]);
		ResourceId id = GetResourceManager()->RegisterResource(res);

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

			{
				SCOPED_SERIALISE_CONTEXT(GEN_QUERIES);
				Serialise_glGenQueries(1, ids+i);

				chunk = scope.Get();
			}

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

			record->AddChunk(chunk);
		}
		else
		{
			GetResourceManager()->AddLiveResource(id, res);
		}
	}
}
void WrappedOpenGL::glCompileShaderIncludeARB(GLuint shader, GLsizei count,
                                              const GLchar *const *path, const GLint *length)
{
  m_Real.glCompileShaderIncludeARB(shader, count, path, length);

  if(m_State >= WRITING)
  {
    GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ShaderRes(GetCtx(), shader));
    RDCASSERT(record);
    {
      SCOPED_SERIALISE_CONTEXT(COMPILESHADERINCLUDE);
      Serialise_glCompileShaderIncludeARB(shader, count, path, length);

      record->AddChunk(scope.Get());
    }
  }
  else
  {
    ResourceId id = GetResourceManager()->GetID(ShaderRes(GetCtx(), shader));

    auto &shadDetails = m_Shaders[id];

    shadDetails.includepaths.clear();
    shadDetails.includepaths.reserve(count);

    for(int32_t i = 0; i < count; i++)
      shadDetails.includepaths.push_back(path[i]);

    shadDetails.Compile(*this);
  }
}
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);
    }
  }
}
GLuint WrappedOpenGL::glCreateShaderProgramv(GLenum type, GLsizei count, const GLchar *const *strings)
{
  GLuint real = m_Real.glCreateShaderProgramv(type, count, strings);

  GLResource res = ProgramRes(GetCtx(), real);
  ResourceId id = GetResourceManager()->RegisterResource(res);

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

    {
      SCOPED_SERIALISE_CONTEXT(CREATE_SHADERPROGRAM);
      Serialise_glCreateShaderProgramv(real, type, count, strings);

      chunk = scope.Get();
    }

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

    // we always want to mark programs as dirty so we can serialise their
    // locations as initial state (and form a remapping table)
    GetResourceManager()->MarkDirtyResource(id);

    record->AddChunk(chunk);
  }
  else
  {
    GetResourceManager()->AddLiveResource(id, res);

    vector<string> src;
    for(GLsizei i = 0; i < count; i++)
      src.push_back(strings[i]);

    GLuint sepprog = MakeSeparableShaderProgram(*this, type, src, NULL);

    auto &progDetails = m_Programs[id];

    progDetails.linked = true;
    progDetails.shaders.push_back(id);
    progDetails.stageShaders[ShaderIdx(type)] = id;

    auto &shadDetails = m_Shaders[id];

    shadDetails.type = type;
    shadDetails.sources.swap(src);
    shadDetails.prog = sepprog;

    shadDetails.Compile(*this);
  }

  return real;
}
void WrappedOpenGL::glBindTexture(GLenum target, GLuint texture)
{
	m_Real.glBindTexture(target, texture);
	
	if(m_State == WRITING_CAPFRAME)
	{
		Chunk *chunk = NULL;

		{
			SCOPED_SERIALISE_CONTEXT(BIND_TEXTURE);
			Serialise_glBindTexture(target, texture);

			chunk = scope.Get();
		}
		
		m_ContextRecord->AddChunk(chunk);
	}
	else if(m_State < WRITING)
	{
		m_Textures[GetResourceManager()->GetID(TextureRes(texture))].curType = target;
	}

	if(texture == 0)
	{
		m_TextureRecord[m_TextureUnit] = NULL;
		return;
	}

	if(m_State >= WRITING)
	{
		GLResourceRecord *r = m_TextureRecord[m_TextureUnit] = GetResourceManager()->GetResourceRecord(TextureRes(texture));

		if(r->datatype)
		{
			// it's illegal to retype a texture
			RDCASSERT(r->datatype == target);
		}
		else
		{
			Chunk *chunk = NULL;

			{
				SCOPED_SERIALISE_CONTEXT(BIND_TEXTURE);
				Serialise_glBindTexture(target, texture);

				chunk = scope.Get();
			}

			r->AddChunk(chunk);
		}
	}
}
void WrappedOpenGL::glTextureBufferRangeEXT(GLuint texture, GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size)
{
	m_Real.glTextureBufferRangeEXT(texture, target, internalformat, buffer, offset, size);
		
	if(m_State >= WRITING)
	{
		GLResourceRecord *record = GetResourceManager()->GetResourceRecord(TextureRes(texture));
		RDCASSERT(record);

		SCOPED_SERIALISE_CONTEXT(TEXBUFFER_RANGE);
		Serialise_glTextureBufferRangeEXT(texture, target, internalformat, buffer, offset, size);

		record->AddChunk(scope.Get());
	}
}
void WrappedOpenGL::glProgramParameteri(GLuint program, GLenum pname, GLint value)
{
  m_Real.glProgramParameteri(program, pname, value);

  if(m_State >= WRITING)
  {
    GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), program));
    RDCASSERT(record);
    {
      SCOPED_SERIALISE_CONTEXT(PROGRAMPARAMETER);
      Serialise_glProgramParameteri(program, pname, value);

      record->AddChunk(scope.Get());
    }
  }
}
void WrappedOpenGL::glLinkProgram(GLuint program)
{
	m_Real.glLinkProgram(program);
	
	if(m_State >= WRITING)
	{
		GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), program));
		RDCASSERT(record);
		{
			SCOPED_SERIALISE_CONTEXT(LINKPROGRAM);
			Serialise_glLinkProgram(program);

			record->AddChunk(scope.Get());
		}
	}
}
void WrappedOpenGL::glBindFragDataLocation(GLuint program, GLuint color, const GLchar *name)
{
  m_Real.glBindFragDataLocation(program, color, name);

  if(m_State >= WRITING)
  {
    GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), program));
    RDCASSERT(record);
    {
      SCOPED_SERIALISE_CONTEXT(BINDFRAGDATA_LOCATION);
      Serialise_glBindFragDataLocation(program, color, name);

      record->AddChunk(scope.Get());
    }
  }
}
void WrappedOpenGL::glShaderStorageBlockBinding(GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding)
{
	m_Real.glShaderStorageBlockBinding(program, storageBlockIndex, storageBlockBinding);
	
	if(m_State >= WRITING)
	{
		GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), program));
		RDCASSERT(record);
		{
			SCOPED_SERIALISE_CONTEXT(STORAGE_BLOCKBIND);
			Serialise_glShaderStorageBlockBinding(program, storageBlockIndex, storageBlockBinding);

			record->AddChunk(scope.Get());
		}
	}
}
void WrappedOpenGL::glCompileShader(GLuint shader)
{
	m_Real.glCompileShader(shader);
	
	if(m_State >= WRITING)
	{
		GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ShaderRes(GetCtx(), shader));
		RDCASSERT(record);
		{
			SCOPED_SERIALISE_CONTEXT(COMPILESHADER);
			Serialise_glCompileShader(shader);

			record->AddChunk(scope.Get());
		}
	}
}
void WrappedOpenGL::glCompileShaderIncludeARB(GLuint shader, GLsizei count, const GLchar *const*path, const GLint *length)
{
	m_Real.glCompileShaderIncludeARB(shader, count, path, length);
	
	if(m_State >= WRITING)
	{
		GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ShaderRes(GetCtx(), shader));
		RDCASSERT(record);
		{
			SCOPED_SERIALISE_CONTEXT(COMPILESHADERINCLUDE);
			Serialise_glCompileShaderIncludeARB(shader, count, path, length);

			record->AddChunk(scope.Get());
		}
	}
}
void WrappedOpenGL::glTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode)
{
	m_Real.glTransformFeedbackVaryings(program, count, varyings, bufferMode);
	
	if(m_State >= WRITING)
	{
		GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), program));
		RDCASSERT(record);
		{
			SCOPED_SERIALISE_CONTEXT(FEEDBACK_VARYINGS);
			Serialise_glTransformFeedbackVaryings(program, count, varyings, bufferMode);

			record->AddChunk(scope.Get());
		}
	}
}
void WrappedOpenGL::glTexStorage1D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width)
{
	m_Real.glTexStorage1D(target, levels, internalformat, width);
	
	if(m_State >= WRITING)
	{
		GLResourceRecord *record = m_TextureRecord[m_TextureUnit];
		RDCASSERT(record);

		SCOPED_SERIALISE_CONTEXT(TEXSTORAGE1D);
		Serialise_glTextureStorage1DEXT(GetResourceManager()->GetCurrentResource(record->GetResourceID()).name,
																		target, levels, internalformat, width);

		record->AddChunk(scope.Get());
	}
}
void WrappedOpenGL::glShaderSource(GLuint shader, GLsizei count, const GLchar* const *string, const GLint *length)
{
	m_Real.glShaderSource(shader, count, string, length);
	
	if(m_State >= WRITING)
	{
		GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ShaderRes(GetCtx(), shader));
		RDCASSERT(record);
		{
			SCOPED_SERIALISE_CONTEXT(SHADERSOURCE);
			Serialise_glShaderSource(shader, count, string, length);

			record->AddChunk(scope.Get());
		}
	}
}
void WrappedOpenGL::glNamedFramebufferTextureLayerEXT(GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer)
{
	m_Real.glNamedFramebufferTextureLayerEXT(framebuffer, attachment, texture, level, layer);
	
	if(m_State >= WRITING)
	{
		GLResourceRecord *record = GetResourceManager()->GetResourceRecord(FramebufferRes(GetCtx(), framebuffer));

		SCOPED_SERIALISE_CONTEXT(FRAMEBUFFER_TEXLAYER);
		Serialise_glNamedFramebufferTextureLayerEXT(framebuffer, attachment, texture, level, layer);
		
		if(m_State == WRITING_IDLE)
			record->AddChunk(scope.Get());
		else
			m_ContextRecord->AddChunk(scope.Get());
	}
}
void WrappedOpenGL::glDetachShader(GLuint program, GLuint shader)
{
	m_Real.glDetachShader(program, shader);
	
	// check that shader still exists, it might have been deleted. If it has, it's not too important
	// that we detach the shader (only important if the program will attach it elsewhere).
	if(m_State >= WRITING && program != 0 && shader != 0 && GetResourceManager()->HasCurrentResource(ShaderRes(GetCtx(), shader)))
	{
		GLResourceRecord *progRecord = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), program));
		RDCASSERT(progRecord);
		{
			SCOPED_SERIALISE_CONTEXT(DETACHSHADER);
			Serialise_glDetachShader(program, shader);

			progRecord->AddChunk(scope.Get());
		}
	}
}
void WrappedOpenGL::glTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels)
{
	m_Real.glTextureSubImage2DEXT(texture, target, level, xoffset, yoffset, width, height, format, type, pixels);
	
	if(m_State >= WRITING)
	{
		GLResourceRecord *record = GetResourceManager()->GetResourceRecord(TextureRes(texture));
		RDCASSERT(record);

		SCOPED_SERIALISE_CONTEXT(TEXSUBIMAGE2D);
		Serialise_glTextureSubImage2DEXT(texture, target, level, xoffset, yoffset, width, height, format, type, pixels);

		if(m_State == WRITING_CAPFRAME)
			m_ContextRecord->AddChunk(scope.Get());
		else
			record->AddChunk(scope.Get());
	}
}
void WrappedOpenGL::glTextureStorage3DEXT(GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
{
	m_Real.glTextureStorage3DEXT(texture, target, levels, internalformat, width, height, depth);
	
	if(m_State >= WRITING)
	{
		GLResourceRecord *record = GetResourceManager()->GetResourceRecord(TextureRes(texture));
		RDCASSERT(record);

		SCOPED_SERIALISE_CONTEXT(TEXSTORAGE3D);
		Serialise_glTextureStorage3DEXT(texture, target, levels, internalformat, width, height, depth);

		if(m_State == WRITING_CAPFRAME)
			m_ContextRecord->AddChunk(scope.Get());
		else
			record->AddChunk(scope.Get());
	}
}
void WrappedOpenGL::glTextureParameterfvEXT(GLuint texture, GLenum target, GLenum pname, const GLfloat *params)
{
	m_Real.glTextureParameterfvEXT(texture, target, pname, params);
	
	if(m_State >= WRITING)
	{
		GLResourceRecord *record = GetResourceManager()->GetResourceRecord(TextureRes(texture));
		RDCASSERT(record);

		SCOPED_SERIALISE_CONTEXT(TEXPARAMETERFV);
		Serialise_glTextureParameterfvEXT(texture, target, pname, params);

		if(m_State == WRITING_IDLE)
			record->AddChunk(scope.Get());
		else
			m_ContextRecord->AddChunk(scope.Get());
	}
}