Files
renderdoc/renderdoc/driver/gl/gl_device_driver.cpp
T

1644 lines
40 KiB
C++

/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2014 Crytek
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#include "common/common.h"
#include "gl_driver.h"
#pragma region Textures
bool WrappedOpenGL::Serialise_glGenTextures(GLsizei n, GLuint* textures)
{
SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(*textures)));
if(m_State == READING)
{
GLuint real = 0;
m_Real.glGenTextures(1, &real);
GLResource res = TextureRes(real);
ResourceId live = m_ResourceManager->RegisterResource(res);
GetResourceManager()->AddLiveResource(id, res);
m_Textures[live].resource = res;
m_Textures[live].curType = eGL_UNKNOWN_ENUM;
}
return true;
}
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::glDeleteTextures(GLsizei n, const GLuint *textures)
{
m_Real.glDeleteTextures(n, textures);
for(GLsizei i=0; i < n; i++)
GetResourceManager()->UnregisterResource(TextureRes(textures[i]));
}
bool WrappedOpenGL::Serialise_glBindTexture(GLenum target, GLuint texture)
{
SERIALISE_ELEMENT(GLenum, Target, target);
SERIALISE_ELEMENT(ResourceId, Id, GetResourceManager()->GetID(TextureRes(texture)));
if(m_State == WRITING_IDLE)
{
m_TextureRecord[m_TextureUnit]->datatype = Target;
}
else if(m_State < WRITING)
{
GLResource res = GetResourceManager()->GetLiveResource(Id);
m_Real.glBindTexture(Target, res.name);
m_Textures[GetResourceManager()->GetLiveID(Id)].curType = Target;
}
return true;
}
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);
}
}
}
bool WrappedOpenGL::Serialise_glTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
{
SERIALISE_ELEMENT(GLenum, Target, target);
SERIALISE_ELEMENT(uint32_t, Levels, levels);
SERIALISE_ELEMENT(GLenum, Format, internalformat);
SERIALISE_ELEMENT(uint32_t, Width, width);
SERIALISE_ELEMENT(uint32_t, Height, height);
SERIALISE_ELEMENT(ResourceId, id, m_TextureRecord[m_TextureUnit]->GetResourceID());
if(m_State == READING)
{
ResourceId liveId = GetResourceManager()->GetLiveID(id);
m_Textures[liveId].width = Width;
m_Textures[liveId].height = Height;
m_Textures[liveId].depth = 1;
m_Real.glBindTexture(Target, GetResourceManager()->GetLiveResource(id).name);
m_Real.glTexStorage2D(Target, Levels, Format, Width, Height);
}
return true;
}
void WrappedOpenGL::glTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
{
m_Real.glTexStorage2D(target, levels, internalformat, width, height);
if(m_State >= WRITING)
{
RDCASSERT(m_TextureRecord[m_TextureUnit]);
SCOPED_SERIALISE_CONTEXT(TEXSTORAGE2D);
Serialise_glTexStorage2D(target, levels, internalformat, width, height);
m_TextureRecord[m_TextureUnit]->AddChunk(scope.Get());
}
}
bool WrappedOpenGL::Serialise_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels)
{
SERIALISE_ELEMENT(GLenum, Target, target);
SERIALISE_ELEMENT(int32_t, Level, level);
SERIALISE_ELEMENT(int32_t, xoff, xoffset);
SERIALISE_ELEMENT(int32_t, yoff, yoffset);
SERIALISE_ELEMENT(uint32_t, Width, width);
SERIALISE_ELEMENT(uint32_t, Height, height);
SERIALISE_ELEMENT(GLenum, Format, format);
SERIALISE_ELEMENT(GLenum, Type, type);
SERIALISE_ELEMENT(ResourceId, id, m_TextureRecord[m_TextureUnit]->GetResourceID());
GLint align = 1;
m_Real.glGetIntegerv(eGL_UNPACK_ALIGNMENT, &align);
size_t subimageSize = GetByteSize(Width, Height, 1, Format, Type, Level, align);
SERIALISE_ELEMENT_BUF(byte *, buf, pixels, subimageSize);
if(m_State == READING)
{
m_Real.glBindTexture(Target, GetResourceManager()->GetLiveResource(id).name);
m_Real.glTexSubImage2D(Target, Level, xoff, yoff, Width, Height, Format, Type, buf);
delete[] buf;
}
return true;
}
void WrappedOpenGL::glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels)
{
m_Real.glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
RDCASSERT(m_TextureRecord[m_TextureUnit]);
{
SCOPED_SERIALISE_CONTEXT(TEXSUBIMAGE2D);
Serialise_glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
m_TextureRecord[m_TextureUnit]->AddChunk(scope.Get());
}
}
bool WrappedOpenGL::Serialise_glGenerateMipmap(GLenum target)
{
SERIALISE_ELEMENT(GLenum, Target, target);
SERIALISE_ELEMENT(ResourceId, id, m_TextureRecord[m_TextureUnit]->GetResourceID());
if(m_State == READING)
{
m_Real.glBindTexture(Target, GetResourceManager()->GetLiveResource(id).name);
m_Real.glGenerateMipmap(Target);
}
return true;
}
void WrappedOpenGL::glGenerateMipmap(GLenum target)
{
m_Real.glGenerateMipmap(target);
RDCASSERT(m_TextureRecord[m_TextureUnit]);
{
SCOPED_SERIALISE_CONTEXT(GENERATE_MIPMAP);
Serialise_glGenerateMipmap(target);
m_TextureRecord[m_TextureUnit]->AddChunk(scope.Get());
}
}
bool WrappedOpenGL::Serialise_glTexParameteri(GLenum target, GLenum pname, GLint param)
{
SERIALISE_ELEMENT(GLenum, Target, target);
SERIALISE_ELEMENT(GLenum, PName, pname);
SERIALISE_ELEMENT(int32_t, Param, param);
if(m_State < WRITING)
{
glTexParameteri(Target, PName, Param);
}
return true;
}
void WrappedOpenGL::glTexParameteri(GLenum target, GLenum pname, GLint param)
{
m_Real.glTexParameteri(target, pname, param);
if(m_State >= WRITING)
{
RDCASSERT(m_TextureRecord[m_TextureUnit]);
SCOPED_SERIALISE_CONTEXT(TEXPARAMETERI);
Serialise_glTexParameteri(target, pname, param);
if(m_State == WRITING_IDLE)
m_TextureRecord[m_TextureUnit]->AddChunk(scope.Get());
else
m_ContextRecord->AddChunk(scope.Get());
}
}
bool WrappedOpenGL::Serialise_glGenSamplers(GLsizei n, GLuint* samplers)
{
SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(SamplerRes(*samplers)));
if(m_State == READING)
{
GLuint real = 0;
m_Real.glGenSamplers(1, &real);
GLResource res = SamplerRes(real);
ResourceId live = m_ResourceManager->RegisterResource(res);
GetResourceManager()->AddLiveResource(id, res);
}
return true;
}
void WrappedOpenGL::glGenSamplers(GLsizei count, GLuint *samplers)
{
m_Real.glGenSamplers(count, samplers);
for(GLsizei i=0; i < count; i++)
{
GLResource res = SamplerRes(samplers[i]);
ResourceId id = GetResourceManager()->RegisterResource(res);
if(m_State >= WRITING)
{
Chunk *chunk = NULL;
{
SCOPED_SERIALISE_CONTEXT(GEN_SAMPLERS);
Serialise_glGenSamplers(1, samplers+i);
chunk = scope.Get();
}
GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id);
RDCASSERT(record);
record->AddChunk(chunk);
}
else
{
GetResourceManager()->AddLiveResource(id, res);
}
}
}
bool WrappedOpenGL::Serialise_glBindSampler(GLuint unit, GLuint sampler)
{
SERIALISE_ELEMENT(uint32_t, Unit, unit);
SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(SamplerRes(sampler)));
if(m_State < WRITING)
{
GLResource res = GetResourceManager()->GetLiveResource(id);
glBindSampler(Unit, res.name);
}
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());
}
}
bool WrappedOpenGL::Serialise_glSamplerParameteri(GLuint sampler, GLenum pname, GLint param)
{
SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(SamplerRes(sampler)));
SERIALISE_ELEMENT(GLenum, PName, pname);
SERIALISE_ELEMENT(int32_t, Param, param);
if(m_State < WRITING)
{
GLResource res = GetResourceManager()->GetLiveResource(id);
glSamplerParameteri(res.name, pname, param);
}
return true;
}
void WrappedOpenGL::glSamplerParameteri(GLuint sampler, GLenum pname, GLint param)
{
m_Real.glSamplerParameteri(sampler, pname, param);
if(m_State >= WRITING)
{
SCOPED_SERIALISE_CONTEXT(SAMPLER_PARAMETERI);
Serialise_glSamplerParameteri(sampler, pname, param);
if(m_State == WRITING_IDLE)
GetResourceManager()->GetResourceRecord(SamplerRes(sampler))->AddChunk(scope.Get());
else
m_ContextRecord->AddChunk(scope.Get());
}
}
bool WrappedOpenGL::Serialise_glPixelStorei(GLenum pname, GLint param)
{
SERIALISE_ELEMENT(GLenum, PName, pname);
SERIALISE_ELEMENT(int32_t, Param, param);
if(m_State < WRITING)
m_Real.glPixelStorei(PName, Param);
return true;
}
void WrappedOpenGL::glPixelStorei(GLenum pname, GLint param)
{
m_Real.glPixelStorei(pname, param);
RDCASSERT(m_TextureRecord[m_TextureUnit]);
{
SCOPED_SERIALISE_CONTEXT(PIXELSTORE);
Serialise_glPixelStorei(pname, param);
m_TextureRecord[m_TextureUnit]->AddChunk(scope.Get());
}
}
void WrappedOpenGL::glPixelStoref(GLenum pname, GLfloat param)
{
glPixelStorei(pname, (GLint)param);
}
void WrappedOpenGL::glTexImage1D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
{
m_Real.glTexImage1D(target, level, internalformat, width, border, format, type, pixels);
RDCUNIMPLEMENTED();
}
void WrappedOpenGL::glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid * pixels)
{
m_Real.glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
RDCUNIMPLEMENTED();
}
bool WrappedOpenGL::Serialise_glActiveTexture(GLenum texture)
{
SERIALISE_ELEMENT(GLenum, Texture, texture);
if(m_State < WRITING)
m_Real.glActiveTexture(Texture);
return true;
}
void WrappedOpenGL::glActiveTexture(GLenum texture)
{
m_Real.glActiveTexture(texture);
m_TextureUnit = texture-eGL_TEXTURE0;
if(m_State == WRITING_CAPFRAME)
{
Chunk *chunk = NULL;
{
SCOPED_SERIALISE_CONTEXT(ACTIVE_TEXTURE);
Serialise_glActiveTexture(texture);
chunk = scope.Get();
}
m_ContextRecord->AddChunk(chunk);
}
}
#pragma endregion
#pragma region Framebuffers
bool WrappedOpenGL::Serialise_glGenFramebuffers(GLsizei n, GLuint* framebuffers)
{
SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(FramebufferRes(*framebuffers)));
if(m_State == READING)
{
GLuint real = 0;
m_Real.glGenFramebuffers(1, &real);
GLResource res = FramebufferRes(real);
ResourceId live = m_ResourceManager->RegisterResource(res);
GetResourceManager()->AddLiveResource(id, res);
}
return true;
}
void WrappedOpenGL::glGenFramebuffers(GLsizei n, GLuint *framebuffers)
{
m_Real.glGenFramebuffers(n, framebuffers);
for(GLsizei i=0; i < n; i++)
{
GLResource res = FramebufferRes(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);
}
}
}
bool WrappedOpenGL::Serialise_glFramebufferTexture(GLenum target, GLenum attachment, GLuint texture, GLint level)
{
SERIALISE_ELEMENT(GLenum, Target, target);
SERIALISE_ELEMENT(GLenum, Attach, attachment);
SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(texture)));
SERIALISE_ELEMENT(int32_t, Level, level);
if(m_State < WRITING)
{
GLResource res = GetResourceManager()->GetLiveResource(id);
glFramebufferTexture(Target, Attach, res.name, Level);
}
return true;
}
void WrappedOpenGL::glFramebufferTexture(GLenum target, GLenum attachment, GLuint texture, GLint level)
{
m_Real.glFramebufferTexture(target, attachment, texture, level);
if(m_State >= WRITING)
{
SCOPED_SERIALISE_CONTEXT(FRAMEBUFFER_TEX);
Serialise_glFramebufferTexture(target, attachment, texture, level);
if(m_State == WRITING_IDLE)
{
if(target == eGL_DRAW_FRAMEBUFFER || target == eGL_FRAMEBUFFER)
{
if(m_DrawFramebufferRecord)
m_DeviceRecord->AddChunk(scope.Get());
else
m_DrawFramebufferRecord->AddChunk(scope.Get());
}
else
{
if(m_ReadFramebufferRecord)
m_DeviceRecord->AddChunk(scope.Get());
else
m_ReadFramebufferRecord->AddChunk(scope.Get());
}
}
else
m_ContextRecord->AddChunk(scope.Get());
}
}
bool WrappedOpenGL::Serialise_glReadBuffer(GLenum mode)
{
SERIALISE_ELEMENT(GLenum, m, mode);
if(m_State < WRITING)
m_Real.glReadBuffer(m);
return true;
}
void WrappedOpenGL::glReadBuffer(GLenum mode)
{
m_Real.glReadBuffer(mode);
if(m_State >= WRITING)
{
SCOPED_SERIALISE_CONTEXT(READ_BUFFER);
Serialise_glReadBuffer(mode);
if(m_State == WRITING_IDLE)
{
if(m_ReadFramebufferRecord)
m_ReadFramebufferRecord->AddChunk(scope.Get());
else
m_DeviceRecord->AddChunk(scope.Get());
}
else
m_ContextRecord->AddChunk(scope.Get());
}
}
bool WrappedOpenGL::Serialise_glBindFramebuffer(GLenum target, GLuint framebuffer)
{
SERIALISE_ELEMENT(GLenum, Target, target);
SERIALISE_ELEMENT(ResourceId, Id, GetResourceManager()->GetID(FramebufferRes(framebuffer)));
if(m_State <= EXECUTING)
{
if(Id == ResourceId())
{
m_Real.glBindFramebuffer(Target, m_FakeBB_FBO);
}
else
{
GLResource res = GetResourceManager()->GetLiveResource(Id);
m_Real.glBindFramebuffer(Target, res.name);
}
}
return true;
}
void WrappedOpenGL::glBindFramebuffer(GLenum target, GLuint framebuffer)
{
if(m_State == WRITING_CAPFRAME)
{
SCOPED_SERIALISE_CONTEXT(BIND_FRAMEBUFFER);
Serialise_glBindFramebuffer(target, framebuffer);
m_ContextRecord->AddChunk(scope.Get());
}
if(framebuffer == 0 && m_State < WRITING)
framebuffer = m_FakeBB_FBO;
if(target == eGL_DRAW_FRAMEBUFFER || target == eGL_FRAMEBUFFER)
m_DrawFramebufferRecord = GetResourceManager()->GetResourceRecord(FramebufferRes(framebuffer));
else
m_ReadFramebufferRecord = GetResourceManager()->GetResourceRecord(FramebufferRes(framebuffer));
m_Real.glBindFramebuffer(target, framebuffer);
}
bool WrappedOpenGL::Serialise_glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
{
SERIALISE_ELEMENT(int32_t, sX0, srcX0);
SERIALISE_ELEMENT(int32_t, sY0, srcY0);
SERIALISE_ELEMENT(int32_t, sX1, srcX1);
SERIALISE_ELEMENT(int32_t, sY1, srcY1);
SERIALISE_ELEMENT(int32_t, dX0, dstX0);
SERIALISE_ELEMENT(int32_t, dY0, dstY0);
SERIALISE_ELEMENT(int32_t, dX1, dstX1);
SERIALISE_ELEMENT(int32_t, dY1, dstY1);
SERIALISE_ELEMENT(uint32_t, msk, mask);
SERIALISE_ELEMENT(GLenum, flt, filter);
if(m_State <= EXECUTING)
{
m_Real.glBlitFramebuffer(sX0, sY0, sX1, sY1, dX0, dY0, dX1, dY1, msk, flt);
}
return true;
}
void WrappedOpenGL::glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
{
if(m_State == WRITING_CAPFRAME)
{
SCOPED_SERIALISE_CONTEXT(BLIT_FRAMEBUFFER);
Serialise_glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
m_ContextRecord->AddChunk(scope.Get());
}
m_Real.glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
}
void WrappedOpenGL::glDeleteFramebuffers(GLsizei n, const GLuint *framebuffers)
{
m_Real.glDeleteFramebuffers(n, framebuffers);
for(GLsizei i=0; i < n; i++)
GetResourceManager()->UnregisterResource(FramebufferRes(framebuffers[i]));
}
void WrappedOpenGL::glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint *params)
{
m_Real.glGetFramebufferAttachmentParameteriv(target, attachment, pname, params);
}
GLenum WrappedOpenGL::glCheckFramebufferStatus(GLenum target)
{
return m_Real.glCheckFramebufferStatus(target);
}
#pragma endregion
#pragma region Shaders / Programs
bool WrappedOpenGL::Serialise_glCreateShader(GLuint shader, GLenum type)
{
SERIALISE_ELEMENT(GLenum, Type, type);
SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ShaderRes(shader)));
if(m_State == READING)
{
GLuint real = m_Real.glCreateShader(Type);
GLResource res = ShaderRes(real);
ResourceId liveId = GetResourceManager()->RegisterResource(res);
m_Shaders[liveId].type = Type;
if(m_State >= WRITING)
{
RDCUNIMPLEMENTED();
}
else
{
GetResourceManager()->AddLiveResource(id, res);
}
}
return true;
}
GLuint WrappedOpenGL::glCreateShader(GLenum type)
{
GLuint real = m_Real.glCreateShader(type);
GLResource res = ShaderRes(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);
}
return real;
}
bool WrappedOpenGL::Serialise_glShaderSource(GLuint shader, GLsizei count, const GLchar* const *source, const GLint *length)
{
SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ShaderRes(shader)));
SERIALISE_ELEMENT(uint32_t, Count, count);
vector<string> srcs;
for(uint32_t i=0; i < Count; i++)
{
string s;
if(source)
s = length ? string(source[i], source[i] + length[i]) : string(source[i]);
m_pSerialiser->SerialiseString("source", s);
if(m_State == READING)
srcs.push_back(s);
}
if(m_State == READING)
{
const char **strings = new const char*[srcs.size()];
for(size_t i=0; i < srcs.size(); i++)
strings[i] = srcs[i].c_str();
ResourceId liveId = GetResourceManager()->GetLiveID(id);
for(uint32_t i=0; i < Count; i++)
m_Shaders[liveId].sources.push_back(strings[i]);
m_Real.glShaderSource(GetResourceManager()->GetLiveResource(id).name, Count, strings, NULL);
}
return true;
}
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(shader));
RDCASSERT(record);
{
SCOPED_SERIALISE_CONTEXT(SHADERSOURCE);
Serialise_glShaderSource(shader, count, string, length);
record->AddChunk(scope.Get());
}
}
}
bool WrappedOpenGL::Serialise_glCompileShader(GLuint shader)
{
SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ShaderRes(shader)));
if(m_State == READING)
{
m_Real.glCompileShader(GetResourceManager()->GetLiveResource(id).name);
}
return true;
}
void WrappedOpenGL::glCompileShader(GLuint shader)
{
m_Real.glCompileShader(shader);
if(m_State >= WRITING)
{
GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ShaderRes(shader));
RDCASSERT(record);
{
SCOPED_SERIALISE_CONTEXT(COMPILESHADER);
Serialise_glCompileShader(shader);
record->AddChunk(scope.Get());
}
}
}
void WrappedOpenGL::glDeleteShader(GLuint shader)
{
m_Real.glDeleteShader(shader);
GetResourceManager()->UnregisterResource(ShaderRes(shader));
}
bool WrappedOpenGL::Serialise_glAttachShader(GLuint program, GLuint shader)
{
SERIALISE_ELEMENT(ResourceId, progid, GetResourceManager()->GetID(ProgramRes(program)));
SERIALISE_ELEMENT(ResourceId, shadid, GetResourceManager()->GetID(ShaderRes(shader)));
if(m_State == READING)
{
ResourceId liveProgId = GetResourceManager()->GetLiveID(progid);
ResourceId liveShadId = GetResourceManager()->GetLiveID(shadid);
m_Programs[liveProgId].shaders.push_back(liveShadId);
m_Real.glAttachShader(GetResourceManager()->GetLiveResource(progid).name,
GetResourceManager()->GetLiveResource(shadid).name);
}
return true;
}
void WrappedOpenGL::glAttachShader(GLuint program, GLuint shader)
{
m_Real.glAttachShader(program, shader);
if(m_State >= WRITING)
{
GLResourceRecord *progRecord = GetResourceManager()->GetResourceRecord(ProgramRes(program));
GLResourceRecord *shadRecord = GetResourceManager()->GetResourceRecord(ShaderRes(shader));
RDCASSERT(progRecord && shadRecord);
{
SCOPED_SERIALISE_CONTEXT(ATTACHSHADER);
Serialise_glAttachShader(program, shader);
progRecord->AddParent(shadRecord);
progRecord->AddChunk(scope.Get());
}
}
}
bool WrappedOpenGL::Serialise_glCreateProgram(GLuint program)
{
SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ProgramRes(program)));
if(m_State == READING)
{
GLuint real = m_Real.glCreateProgram();
GLResource res = ProgramRes(real);
m_ResourceManager->RegisterResource(res);
GetResourceManager()->AddLiveResource(id, res);
}
return true;
}
GLuint WrappedOpenGL::glCreateProgram()
{
GLuint real = m_Real.glCreateProgram();
GLResource res = ProgramRes(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);
record->AddChunk(chunk);
}
else
{
GetResourceManager()->AddLiveResource(id, res);
}
return real;
}
bool WrappedOpenGL::Serialise_glLinkProgram(GLuint program)
{
SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ProgramRes(program)));
if(m_State == READING)
{
m_Real.glLinkProgram(GetResourceManager()->GetLiveResource(id).name);
}
return true;
}
void WrappedOpenGL::glLinkProgram(GLuint program)
{
m_Real.glLinkProgram(program);
if(m_State >= WRITING)
{
GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ProgramRes(program));
RDCASSERT(record);
{
SCOPED_SERIALISE_CONTEXT(LINKPROGRAM);
Serialise_glLinkProgram(program);
record->AddChunk(scope.Get());
}
}
}
void WrappedOpenGL::glDeleteProgram(GLuint program)
{
m_Real.glDeleteProgram(program);
GetResourceManager()->UnregisterResource(ProgramRes(program));
}
bool WrappedOpenGL::Serialise_glUseProgram(GLuint program)
{
SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ProgramRes(program)));
if(m_State <= EXECUTING)
{
m_Real.glUseProgram(GetResourceManager()->GetLiveResource(id).name);
}
return true;
}
void WrappedOpenGL::glUseProgram(GLuint program)
{
m_Real.glUseProgram(program);
if(m_State == WRITING_CAPFRAME)
{
SCOPED_SERIALISE_CONTEXT(USEPROGRAM);
Serialise_glUseProgram(program);
m_ContextRecord->AddChunk(scope.Get());
}
}
#pragma region Uniforms
bool WrappedOpenGL::Serialise_glUniformMatrix(GLint location, GLsizei count, GLboolean transpose, const void *value, UniformType type)
{
SERIALISE_ELEMENT(UniformType, Type, type);
SERIALISE_ELEMENT(int32_t, Loc, location);
SERIALISE_ELEMENT(uint32_t, Count, count);
SERIALISE_ELEMENT(uint8_t, Transpose, transpose);
size_t elemsPerMat = 0;
switch(Type)
{
case MAT4FV: elemsPerMat = 16; break;
default:
RDCERR("Unexpected uniform type to Serialise_glUniformMatrix: %d", Type);
}
if(m_State >= WRITING)
{
m_pSerialiser->RawWriteBytes(value, sizeof(float)*elemsPerMat*Count);
}
else if(m_State <= EXECUTING)
{
value = m_pSerialiser->RawReadBytes(sizeof(float)*elemsPerMat*Count);
switch(Type)
{
case MAT4FV: m_Real.glUniformMatrix4fv(Loc, Count, Transpose, (const GLfloat *)value); break;
default:
RDCERR("Unexpected uniform type to Serialise_glUniformMatrix: %d", Type);
}
}
if(m_pSerialiser->GetDebugText())
{
switch(Type)
{
case MAT4FV:
{
float *f = (float *)value;
if(Transpose)
{
m_pSerialiser->DebugPrint("value: {%f %f %f %f}\n", f[0], f[4], f[8], f[12]);
m_pSerialiser->DebugPrint("value: {%f %f %f %f}\n", f[1], f[5], f[9], f[13]);
m_pSerialiser->DebugPrint("value: {%f %f %f %f}\n", f[2], f[6], f[10], f[14]);
m_pSerialiser->DebugPrint("value: {%f %f %f %f}\n", f[3], f[7], f[11], f[15]);
}
else
{
m_pSerialiser->DebugPrint("value: {%f %f %f %f}\n", f[0], f[1], f[2], f[3]);
m_pSerialiser->DebugPrint("value: {%f %f %f %f}\n", f[4], f[5], f[6], f[7]);
m_pSerialiser->DebugPrint("value: {%f %f %f %f}\n", f[8], f[9], f[10], f[11]);
m_pSerialiser->DebugPrint("value: {%f %f %f %f}\n", f[12], f[13], f[14], f[15]);
}
break;
}
default:
RDCERR("Unexpected uniform type to Serialise_glUniformVector: %d", Type);
}
}
return true;
}
void WrappedOpenGL::glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
{
m_Real.glUniformMatrix4fv(location, count, transpose, value);
if(m_State == WRITING_CAPFRAME)
{
SCOPED_SERIALISE_CONTEXT(UNIFORM_MATRIX);
Serialise_glUniformMatrix(location, count, transpose, value, MAT4FV);
m_ContextRecord->AddChunk(scope.Get());
}
}
bool WrappedOpenGL::Serialise_glUniformVector(GLint location, GLsizei count, const void *value, UniformType type)
{
SERIALISE_ELEMENT(UniformType, Type, type);
SERIALISE_ELEMENT(int32_t, Loc, location);
SERIALISE_ELEMENT(uint32_t, Count, count);
size_t elemsPerVec = 0;
switch(Type)
{
case VEC3FV: elemsPerVec = 3; break;
case VEC4FV: elemsPerVec = 4; break;
default:
RDCERR("Unexpected uniform type to Serialise_glUniformVector: %d", Type);
}
if(m_State >= WRITING)
{
m_pSerialiser->RawWriteBytes(value, sizeof(float)*elemsPerVec*Count);
}
else if(m_State <= EXECUTING)
{
value = m_pSerialiser->RawReadBytes(sizeof(float)*elemsPerVec*Count);
switch(Type)
{
case VEC3FV: m_Real.glUniform3fv(Loc, Count, (const GLfloat *)value); break;
case VEC4FV: m_Real.glUniform4fv(Loc, Count, (const GLfloat *)value); break;
default:
RDCERR("Unexpected uniform type to Serialise_glUniformVector: %d", Type);
}
}
if(m_pSerialiser->GetDebugText())
{
switch(Type)
{
case VEC3FV:
{
float *f = (float *)value;
m_pSerialiser->DebugPrint("value: {%f %f %f}\n", f[0], f[1], f[2]);
break;
}
case VEC4FV:
{
float *f = (float *)value;
m_pSerialiser->DebugPrint("value: {%f %f %f %f}\n", f[0], f[1], f[2], f[3]);
break;
}
default:
RDCERR("Unexpected uniform type to Serialise_glUniformVector: %d", Type);
}
}
return true;
}
void WrappedOpenGL::glUniform3fv(GLint location, GLsizei count, const GLfloat *value)
{
m_Real.glUniform3fv(location, count, value);
if(m_State == WRITING_CAPFRAME)
{
SCOPED_SERIALISE_CONTEXT(UNIFORM_VECTOR);
Serialise_glUniformVector(location, count, value, VEC3FV);
m_ContextRecord->AddChunk(scope.Get());
}
}
void WrappedOpenGL::glUniform4fv(GLint location, GLsizei count, const GLfloat *value)
{
m_Real.glUniform4fv(location, count, value);
if(m_State == WRITING_CAPFRAME)
{
SCOPED_SERIALISE_CONTEXT(UNIFORM_VECTOR);
Serialise_glUniformVector(location, count, value, VEC4FV);
m_ContextRecord->AddChunk(scope.Get());
}
}
#pragma endregion
#pragma endregion
#pragma region Buffers
bool WrappedOpenGL::Serialise_glGenBuffers(GLsizei n, GLuint* textures)
{
SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(BufferRes(*textures)));
if(m_State == READING)
{
GLuint real = 0;
m_Real.glGenBuffers(1, &real);
GLResource res = BufferRes(real);
ResourceId live = m_ResourceManager->RegisterResource(res);
GetResourceManager()->AddLiveResource(id, res);
m_Buffers[live].resource = res;
m_Buffers[live].curType = eGL_UNKNOWN_ENUM;
}
return true;
}
void WrappedOpenGL::glGenBuffers(GLsizei n, GLuint *buffers)
{
m_Real.glGenBuffers(n, buffers);
for(GLsizei i=0; i < n; i++)
{
GLResource res = BufferRes(buffers[i]);
ResourceId id = GetResourceManager()->RegisterResource(res);
if(m_State >= WRITING)
{
Chunk *chunk = NULL;
{
SCOPED_SERIALISE_CONTEXT(GEN_BUFFER);
Serialise_glGenBuffers(1, buffers+i);
chunk = scope.Get();
}
GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id);
RDCASSERT(record);
record->AddChunk(chunk);
}
else
{
GetResourceManager()->AddLiveResource(id, res);
}
}
}
size_t WrappedOpenGL::BufferIdx(GLenum buf)
{
switch(buf)
{
case eGL_ARRAY_BUFFER: return 0;
case eGL_ATOMIC_COUNTER_BUFFER: return 1;
case eGL_COPY_READ_BUFFER: return 2;
case eGL_COPY_WRITE_BUFFER: return 3;
case eGL_DRAW_INDIRECT_BUFFER: return 4;
case eGL_DISPATCH_INDIRECT_BUFFER: return 5;
case eGL_ELEMENT_ARRAY_BUFFER: return 6;
case eGL_PIXEL_PACK_BUFFER: return 7;
case eGL_PIXEL_UNPACK_BUFFER: return 8;
case eGL_QUERY_BUFFER: return 9;
case eGL_SHADER_STORAGE_BUFFER: return 10;
case eGL_TEXTURE_BUFFER: return 11;
case eGL_TRANSFORM_FEEDBACK_BUFFER: return 12;
case eGL_UNIFORM_BUFFER: return 13;
default:
RDCERR("Unexpected enum as buffer target: %hs", ToStr::Get(buf).c_str());
}
return 0;
}
bool WrappedOpenGL::Serialise_glBindBuffer(GLenum target, GLuint buffer)
{
SERIALISE_ELEMENT(GLenum, Target, target);
SERIALISE_ELEMENT(ResourceId, Id, GetResourceManager()->GetID(BufferRes(buffer)));
if(m_State >= WRITING)
{
size_t idx = BufferIdx(target);
m_BufferRecord[idx]->datatype = Target;
}
else if(m_State < WRITING)
{
GLResource res = GetResourceManager()->GetLiveResource(Id);
m_Real.glBindBuffer(Target, res.name);
m_Buffers[GetResourceManager()->GetLiveID(Id)].curType = Target;
}
return true;
}
void WrappedOpenGL::glBindBuffer(GLenum target, GLuint buffer)
{
m_Real.glBindBuffer(target, buffer);
if(m_State == WRITING_CAPFRAME)
{
Chunk *chunk = NULL;
{
SCOPED_SERIALISE_CONTEXT(BIND_BUFFER);
Serialise_glBindBuffer(target, buffer);
chunk = scope.Get();
}
m_ContextRecord->AddChunk(chunk);
}
size_t idx = BufferIdx(target);
if(buffer == 0)
{
m_BufferRecord[idx] = NULL;
return;
}
if(m_State >= WRITING)
{
GLResourceRecord *r = m_BufferRecord[idx] = GetResourceManager()->GetResourceRecord(BufferRes(buffer));
// it's legal to re-type buffers, generate another BindBuffer chunk to rename
if(r->datatype != target)
{
Chunk *chunk = NULL;
{
SCOPED_SERIALISE_CONTEXT(BIND_BUFFER);
Serialise_glBindBuffer(target, buffer);
chunk = scope.Get();
}
r->AddChunk(chunk);
}
}
}
bool WrappedOpenGL::Serialise_glBufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage)
{
SERIALISE_ELEMENT(GLenum, Target, target);
SERIALISE_ELEMENT(uint64_t, Bytesize, (uint64_t)size);
SERIALISE_ELEMENT_BUF(byte *, bytes, data, (size_t)Bytesize);
SERIALISE_ELEMENT(GLenum, Usage, usage);
SERIALISE_ELEMENT(ResourceId, id, m_BufferRecord[BufferIdx(target)]->GetResourceID());
if(m_State == READING)
{
GLResource res = GetResourceManager()->GetLiveResource(id);
m_Real.glBindBuffer(Target, res.name);
m_Real.glBufferData(Target, (GLsizeiptr)Bytesize, bytes, Usage);
m_Buffers[GetResourceManager()->GetLiveID(id)].size = Bytesize;
SAFE_DELETE_ARRAY(bytes);
}
return true;
}
void WrappedOpenGL::glBufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage)
{
m_Real.glBufferData(target, size, data, usage);
size_t idx = BufferIdx(target);
if(m_State >= WRITING)
{
RDCASSERT(m_BufferRecord[idx]);
SCOPED_SERIALISE_CONTEXT(BUFFERDATA);
Serialise_glBufferData(target, size, data, usage);
m_BufferRecord[idx]->AddChunk(scope.Get());
}
}
bool WrappedOpenGL::Serialise_glBindBufferBase(GLenum target, GLuint index, GLuint buffer)
{
SERIALISE_ELEMENT(GLenum, Target, target);
SERIALISE_ELEMENT(uint32_t, Index, index);
SERIALISE_ELEMENT(ResourceId, id, m_BufferRecord[BufferIdx(target)]->GetResourceID());
if(m_State < WRITING)
{
GLResource res = GetResourceManager()->GetLiveResource(id);
m_Real.glBindBufferBase(Target, Index, res.name);
}
return true;
}
void WrappedOpenGL::glBindBufferBase(GLenum target, GLuint index, GLuint buffer)
{
if(m_State == WRITING_CAPFRAME)
{
SCOPED_SERIALISE_CONTEXT(BIND_BUFFER_BASE);
Serialise_glBindBufferBase(target, index, buffer);
m_ContextRecord->AddChunk(scope.Get());
}
m_Real.glBindBufferBase(target, index, buffer);
}
bool WrappedOpenGL::Serialise_glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size)
{
SERIALISE_ELEMENT(GLenum, Target, target);
SERIALISE_ELEMENT(uint32_t, Index, index);
SERIALISE_ELEMENT(ResourceId, id, m_BufferRecord[BufferIdx(target)]->GetResourceID());
SERIALISE_ELEMENT(uint64_t, Offset, (uint64_t)offset);
SERIALISE_ELEMENT(uint64_t, Size, (uint64_t)size);
if(m_State < WRITING)
{
GLResource res = GetResourceManager()->GetLiveResource(id);
m_Real.glBindBufferRange(Target, Index, res.name, (GLintptr)Offset, (GLsizeiptr)Size);
}
return true;
}
void WrappedOpenGL::glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size)
{
if(m_State == WRITING_CAPFRAME)
{
SCOPED_SERIALISE_CONTEXT(BIND_BUFFER_RANGE);
Serialise_glBindBufferRange(target, index, buffer, offset, size);
m_ContextRecord->AddChunk(scope.Get());
}
m_Real.glBindBufferRange(target, index, buffer, offset, size);
}
void *WrappedOpenGL::glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
{
if(m_State >= WRITING)
{
RDCUNIMPLEMENTED();
}
return m_Real.glMapBufferRange(target, offset, length, access);
}
GLboolean WrappedOpenGL::glUnmapBuffer(GLenum target)
{
if(m_State >= WRITING)
{
RDCUNIMPLEMENTED();
}
return m_Real.glUnmapBuffer(target);
}
bool WrappedOpenGL::Serialise_glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer)
{
SERIALISE_ELEMENT(uint32_t, Index, index);
SERIALISE_ELEMENT(int32_t, Size, size);
SERIALISE_ELEMENT(GLenum, Type, type);
SERIALISE_ELEMENT(uint8_t, Norm, normalized);
SERIALISE_ELEMENT(uint32_t, Stride, stride);
SERIALISE_ELEMENT(uint64_t, Offset, (uint64_t)pointer);
SERIALISE_ELEMENT(ResourceId, id, m_VertexArrayRecord ? m_VertexArrayRecord->GetResourceID() : ResourceId());
if(m_State < WRITING)
{
if(id != ResourceId())
{
GLResource res = GetResourceManager()->GetLiveResource(id);
m_Real.glBindVertexArray(res.name);
}
else
{
m_Real.glBindVertexArray(0);
}
m_Real.glVertexAttribPointer(Index, Size, Type, Norm, Stride, (const void *)Offset);
}
return true;
}
void WrappedOpenGL::glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer)
{
m_Real.glVertexAttribPointer(index, size, type, normalized, stride, pointer);
GLResourceRecord *r = m_VertexArrayRecord ? m_VertexArrayRecord : m_DeviceRecord;
RDCASSERT(r);
if(m_State >= WRITING)
{
SCOPED_SERIALISE_CONTEXT(VERTEXATTRIBPOINTER);
Serialise_glVertexAttribPointer(index, size, type, normalized, stride, pointer);
r->AddChunk(scope.Get());
}
}
bool WrappedOpenGL::Serialise_glEnableVertexAttribArray(GLuint index)
{
SERIALISE_ELEMENT(uint32_t, Index, index);
if(m_State < WRITING)
{
m_Real.glEnableVertexAttribArray(Index);
}
return true;
}
void WrappedOpenGL::glEnableVertexAttribArray(GLuint index)
{
m_Real.glEnableVertexAttribArray(index);
GLResourceRecord *r = m_VertexArrayRecord ? m_VertexArrayRecord : m_DeviceRecord;
RDCASSERT(r);
if(m_State >= WRITING)
{
SCOPED_SERIALISE_CONTEXT(ENABLEVERTEXATTRIBARRAY);
Serialise_glEnableVertexAttribArray(index);
r->AddChunk(scope.Get());
}
}
bool WrappedOpenGL::Serialise_glDisableVertexAttribArray(GLuint index)
{
SERIALISE_ELEMENT(uint32_t, Index, index);
if(m_State < WRITING)
{
m_Real.glDisableVertexAttribArray(Index);
}
return true;
}
void WrappedOpenGL::glDisableVertexAttribArray(GLuint index)
{
m_Real.glDisableVertexAttribArray(index);
GLResourceRecord *r = m_VertexArrayRecord ? m_VertexArrayRecord : m_DeviceRecord;
RDCASSERT(r);
if(m_State >= WRITING)
{
SCOPED_SERIALISE_CONTEXT(DISABLEVERTEXATTRIBARRAY);
Serialise_glDisableVertexAttribArray(index);
r->AddChunk(scope.Get());
}
}
bool WrappedOpenGL::Serialise_glGenVertexArrays(GLsizei n, GLuint* arrays)
{
SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(VertexArrayRes(*arrays)));
if(m_State == READING)
{
GLuint real = 0;
m_Real.glGenVertexArrays(1, &real);
GLResource res = VertexArrayRes(real);
m_ResourceManager->RegisterResource(res);
GetResourceManager()->AddLiveResource(id, res);
}
return true;
}
void WrappedOpenGL::glGenVertexArrays(GLsizei n, GLuint *arrays)
{
m_Real.glGenVertexArrays(n, arrays);
for(GLsizei i=0; i < n; i++)
{
GLResource res = VertexArrayRes(arrays[i]);
ResourceId id = GetResourceManager()->RegisterResource(res);
if(m_State >= WRITING)
{
Chunk *chunk = NULL;
{
SCOPED_SERIALISE_CONTEXT(GEN_VERTEXARRAY);
Serialise_glGenVertexArrays(1, arrays+i);
chunk = scope.Get();
}
GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id);
RDCASSERT(record);
record->AddChunk(chunk);
}
else
{
GetResourceManager()->AddLiveResource(id, res);
}
}
}
bool WrappedOpenGL::Serialise_glBindVertexArray(GLuint array)
{
SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(VertexArrayRes(array)));
if(m_State <= EXECUTING)
{
m_Real.glBindVertexArray(GetResourceManager()->GetLiveResource(id).name);
}
return true;
}
void WrappedOpenGL::glBindVertexArray(GLuint array)
{
m_Real.glBindVertexArray(array);
if(m_State >= WRITING)
{
if(array == 0)
{
m_VertexArrayRecord = NULL;
}
else
{
m_VertexArrayRecord = GetResourceManager()->GetResourceRecord(VertexArrayRes(array));
}
}
if(m_State == WRITING_CAPFRAME)
{
SCOPED_SERIALISE_CONTEXT(BINDVERTEXARRAY);
Serialise_glBindVertexArray(array);
m_ContextRecord->AddChunk(scope.Get());
}
}
void WrappedOpenGL::glDeleteBuffers(GLsizei n, const GLuint *buffers)
{
m_Real.glDeleteBuffers(n, buffers);
for(GLsizei i=0; i < n; i++)
GetResourceManager()->UnregisterResource(BufferRes(buffers[i]));
}
void WrappedOpenGL::glDeleteVertexArrays(GLsizei n, const GLuint *arrays)
{
m_Real.glDeleteVertexArrays(n, arrays);
for(GLsizei i=0; i < n; i++)
GetResourceManager()->UnregisterResource(VertexArrayRes(arrays[i]));
}
#pragma endregion