Detect double freeing resources.
This commit is contained in:
parent
d79032e21b
commit
b9c1deceee
32
src/bgfx.cpp
32
src/bgfx.cpp
@ -1440,44 +1440,44 @@ namespace bgfx
|
||||
|
||||
void Context::freeAllHandles(Frame* _frame)
|
||||
{
|
||||
for (uint16_t ii = 0, num = _frame->m_numFreeIndexBufferHandles; ii < num; ++ii)
|
||||
for (uint16_t ii = 0, num = _frame->m_freeIndexBuffer.getNumQueued(); ii < num; ++ii)
|
||||
{
|
||||
m_indexBufferHandle.free(_frame->m_freeIndexBufferHandle[ii].idx);
|
||||
m_indexBufferHandle.free(_frame->m_freeIndexBuffer.get(ii).idx);
|
||||
}
|
||||
|
||||
for (uint16_t ii = 0, num = _frame->m_numFreeVertexBufferHandles; ii < num; ++ii)
|
||||
for (uint16_t ii = 0, num = _frame->m_freeVertexBuffer.getNumQueued(); ii < num; ++ii)
|
||||
{
|
||||
destroyVertexBufferInternal(_frame->m_freeVertexBufferHandle[ii]);
|
||||
destroyVertexBufferInternal(_frame->m_freeVertexBuffer.get(ii));
|
||||
}
|
||||
|
||||
for (uint16_t ii = 0, num = _frame->m_numFreeVertexDeclHandles; ii < num; ++ii)
|
||||
for (uint16_t ii = 0, num = _frame->m_freeVertexDecl.getNumQueued(); ii < num; ++ii)
|
||||
{
|
||||
m_vertexDeclHandle.free(_frame->m_freeVertexDeclHandle[ii].idx);
|
||||
m_vertexDeclHandle.free(_frame->m_freeVertexDecl.get(ii).idx);
|
||||
}
|
||||
|
||||
for (uint16_t ii = 0, num = _frame->m_numFreeShaderHandles; ii < num; ++ii)
|
||||
for (uint16_t ii = 0, num = _frame->m_freeShader.getNumQueued(); ii < num; ++ii)
|
||||
{
|
||||
m_shaderHandle.free(_frame->m_freeShaderHandle[ii].idx);
|
||||
m_shaderHandle.free(_frame->m_freeShader.get(ii).idx);
|
||||
}
|
||||
|
||||
for (uint16_t ii = 0, num = _frame->m_numFreeProgramHandles; ii < num; ++ii)
|
||||
for (uint16_t ii = 0, num = _frame->m_freeProgram.getNumQueued(); ii < num; ++ii)
|
||||
{
|
||||
m_programHandle.free(_frame->m_freeProgramHandle[ii].idx);
|
||||
m_programHandle.free(_frame->m_freeProgram.get(ii).idx);
|
||||
}
|
||||
|
||||
for (uint16_t ii = 0, num = _frame->m_numFreeTextureHandles; ii < num; ++ii)
|
||||
for (uint16_t ii = 0, num = _frame->m_freeTexture.getNumQueued(); ii < num; ++ii)
|
||||
{
|
||||
m_textureHandle.free(_frame->m_freeTextureHandle[ii].idx);
|
||||
m_textureHandle.free(_frame->m_freeTexture.get(ii).idx);
|
||||
}
|
||||
|
||||
for (uint16_t ii = 0, num = _frame->m_numFreeFrameBufferHandles; ii < num; ++ii)
|
||||
for (uint16_t ii = 0, num = _frame->m_freeFrameBuffer.getNumQueued(); ii < num; ++ii)
|
||||
{
|
||||
m_frameBufferHandle.free(_frame->m_freeFrameBufferHandle[ii].idx);
|
||||
m_frameBufferHandle.free(_frame->m_freeFrameBuffer.get(ii).idx);
|
||||
}
|
||||
|
||||
for (uint16_t ii = 0, num = _frame->m_numFreeUniformHandles; ii < num; ++ii)
|
||||
for (uint16_t ii = 0, num = _frame->m_freeUniform.getNumQueued(); ii < num; ++ii)
|
||||
{
|
||||
m_uniformHandle.free(_frame->m_freeUniformHandle[ii].idx);
|
||||
m_uniformHandle.free(_frame->m_freeUniform.get(ii).idx);
|
||||
}
|
||||
}
|
||||
|
||||
|
166
src/bgfx_p.h
166
src/bgfx_p.h
@ -1757,64 +1757,56 @@ namespace bgfx
|
||||
m_uniformBuffer->writeUniform(_type, _handle.idx, _value, _num);
|
||||
}
|
||||
|
||||
void free(IndexBufferHandle _handle)
|
||||
bool free(IndexBufferHandle _handle)
|
||||
{
|
||||
m_freeIndexBufferHandle[m_numFreeIndexBufferHandles] = _handle;
|
||||
++m_numFreeIndexBufferHandles;
|
||||
return m_freeIndexBuffer.queue(_handle);
|
||||
}
|
||||
|
||||
void free(VertexDeclHandle _handle)
|
||||
bool free(VertexDeclHandle _handle)
|
||||
{
|
||||
m_freeVertexDeclHandle[m_numFreeVertexDeclHandles] = _handle;
|
||||
++m_numFreeVertexDeclHandles;
|
||||
return m_freeVertexDecl.queue(_handle);
|
||||
}
|
||||
|
||||
void free(VertexBufferHandle _handle)
|
||||
bool free(VertexBufferHandle _handle)
|
||||
{
|
||||
m_freeVertexBufferHandle[m_numFreeVertexBufferHandles] = _handle;
|
||||
++m_numFreeVertexBufferHandles;
|
||||
return m_freeVertexBuffer.queue(_handle);
|
||||
}
|
||||
|
||||
void free(ShaderHandle _handle)
|
||||
bool free(ShaderHandle _handle)
|
||||
{
|
||||
m_freeShaderHandle[m_numFreeShaderHandles] = _handle;
|
||||
++m_numFreeShaderHandles;
|
||||
return m_freeShader.queue(_handle);
|
||||
}
|
||||
|
||||
void free(ProgramHandle _handle)
|
||||
bool free(ProgramHandle _handle)
|
||||
{
|
||||
m_freeProgramHandle[m_numFreeProgramHandles] = _handle;
|
||||
++m_numFreeProgramHandles;
|
||||
return m_freeProgram.queue(_handle);
|
||||
}
|
||||
|
||||
void free(TextureHandle _handle)
|
||||
bool free(TextureHandle _handle)
|
||||
{
|
||||
m_freeTextureHandle[m_numFreeTextureHandles] = _handle;
|
||||
++m_numFreeTextureHandles;
|
||||
return m_freeTexture.queue(_handle);
|
||||
}
|
||||
|
||||
void free(FrameBufferHandle _handle)
|
||||
bool free(FrameBufferHandle _handle)
|
||||
{
|
||||
m_freeFrameBufferHandle[m_numFreeFrameBufferHandles] = _handle;
|
||||
++m_numFreeFrameBufferHandles;
|
||||
return m_freeFrameBuffer.queue(_handle);
|
||||
}
|
||||
|
||||
void free(UniformHandle _handle)
|
||||
bool free(UniformHandle _handle)
|
||||
{
|
||||
m_freeUniformHandle[m_numFreeUniformHandles] = _handle;
|
||||
++m_numFreeUniformHandles;
|
||||
return m_freeUniform.queue(_handle);
|
||||
}
|
||||
|
||||
void resetFreeHandles()
|
||||
{
|
||||
m_numFreeIndexBufferHandles = 0;
|
||||
m_numFreeVertexDeclHandles = 0;
|
||||
m_numFreeVertexBufferHandles = 0;
|
||||
m_numFreeShaderHandles = 0;
|
||||
m_numFreeProgramHandles = 0;
|
||||
m_numFreeTextureHandles = 0;
|
||||
m_numFreeFrameBufferHandles = 0;
|
||||
m_numFreeUniformHandles = 0;
|
||||
m_freeIndexBuffer.reset();
|
||||
m_freeVertexDecl.reset();
|
||||
m_freeVertexBuffer.reset();
|
||||
m_freeShader.reset();
|
||||
m_freeProgram.reset();
|
||||
m_freeTexture.reset();
|
||||
m_freeFrameBuffer.reset();
|
||||
m_freeUniform.reset();
|
||||
}
|
||||
|
||||
SortKey m_key;
|
||||
@ -1864,24 +1856,71 @@ namespace bgfx
|
||||
CommandBuffer m_cmdPre;
|
||||
CommandBuffer m_cmdPost;
|
||||
|
||||
uint16_t m_numFreeIndexBufferHandles;
|
||||
uint16_t m_numFreeVertexDeclHandles;
|
||||
uint16_t m_numFreeVertexBufferHandles;
|
||||
uint16_t m_numFreeShaderHandles;
|
||||
uint16_t m_numFreeProgramHandles;
|
||||
uint16_t m_numFreeTextureHandles;
|
||||
uint16_t m_numFreeFrameBufferHandles;
|
||||
uint16_t m_numFreeUniformHandles;
|
||||
uint16_t m_numFreeWindowHandles;
|
||||
template<typename Ty, uint32_t Max>
|
||||
struct FreeHandle
|
||||
{
|
||||
FreeHandle()
|
||||
: m_num(0)
|
||||
{
|
||||
}
|
||||
|
||||
bool isQueued(Ty _handle)
|
||||
{
|
||||
for (uint32_t ii = 0, num = m_num; ii < num; ++ii)
|
||||
{
|
||||
if (m_queue[ii].idx == _handle.idx)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool queue(Ty _handle)
|
||||
{
|
||||
if (BX_ENABLED(BGFX_CONFIG_DEBUG) )
|
||||
{
|
||||
if (isQueued(_handle) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
m_queue[m_num] = _handle;
|
||||
++m_num;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
m_num = 0;
|
||||
}
|
||||
|
||||
Ty get(uint16_t _idx) const
|
||||
{
|
||||
return m_queue[_idx];
|
||||
}
|
||||
|
||||
uint16_t getNumQueued() const
|
||||
{
|
||||
return m_num;
|
||||
}
|
||||
|
||||
Ty m_queue[Max];
|
||||
uint16_t m_num;
|
||||
};
|
||||
|
||||
FreeHandle<IndexBufferHandle, BGFX_CONFIG_MAX_INDEX_BUFFERS> m_freeIndexBuffer;
|
||||
FreeHandle<VertexDeclHandle, BGFX_CONFIG_MAX_VERTEX_DECLS> m_freeVertexDecl;
|
||||
FreeHandle<VertexBufferHandle, BGFX_CONFIG_MAX_VERTEX_BUFFERS> m_freeVertexBuffer;
|
||||
FreeHandle<ShaderHandle, BGFX_CONFIG_MAX_SHADERS> m_freeShader;
|
||||
FreeHandle<ProgramHandle, BGFX_CONFIG_MAX_PROGRAMS> m_freeProgram;
|
||||
FreeHandle<TextureHandle, BGFX_CONFIG_MAX_TEXTURES> m_freeTexture;
|
||||
FreeHandle<FrameBufferHandle, BGFX_CONFIG_MAX_FRAME_BUFFERS> m_freeFrameBuffer;
|
||||
FreeHandle<UniformHandle, BGFX_CONFIG_MAX_UNIFORMS> m_freeUniform;
|
||||
|
||||
IndexBufferHandle m_freeIndexBufferHandle[BGFX_CONFIG_MAX_INDEX_BUFFERS];
|
||||
VertexDeclHandle m_freeVertexDeclHandle[BGFX_CONFIG_MAX_VERTEX_DECLS];
|
||||
VertexBufferHandle m_freeVertexBufferHandle[BGFX_CONFIG_MAX_VERTEX_BUFFERS];
|
||||
ShaderHandle m_freeShaderHandle[BGFX_CONFIG_MAX_SHADERS];
|
||||
ProgramHandle m_freeProgramHandle[BGFX_CONFIG_MAX_PROGRAMS];
|
||||
TextureHandle m_freeTextureHandle[BGFX_CONFIG_MAX_TEXTURES];
|
||||
FrameBufferHandle m_freeFrameBufferHandle[BGFX_CONFIG_MAX_FRAME_BUFFERS];
|
||||
UniformHandle m_freeUniformHandle[BGFX_CONFIG_MAX_UNIFORMS];
|
||||
TextVideoMem* m_textVideoMem;
|
||||
HMD m_hmd;
|
||||
Stats m_perfStats;
|
||||
@ -2184,7 +2223,7 @@ namespace bgfx
|
||||
{
|
||||
BX_WARN(1 <= int32_t(_width)
|
||||
&& 1 <= int32_t(_height)
|
||||
, "Frame buffer resolution width or height cannot be 0 (width %d, height %d)."
|
||||
, "Frame buffer resolution width or height must be larger than 0 (width %d, height %d)."
|
||||
, _width
|
||||
, _height
|
||||
);
|
||||
@ -2272,10 +2311,11 @@ namespace bgfx
|
||||
BGFX_API_FUNC(void destroyIndexBuffer(IndexBufferHandle _handle) )
|
||||
{
|
||||
BGFX_CHECK_HANDLE("destroyIndexBuffer", m_indexBufferHandle, _handle);
|
||||
bool ok = m_submit->free(_handle); BX_UNUSED(ok);
|
||||
BX_CHECK(ok, "Index buffer handle %d is already destroyed!", _handle.idx);
|
||||
|
||||
CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyIndexBuffer);
|
||||
cmdbuf.write(_handle);
|
||||
m_submit->free(_handle);
|
||||
}
|
||||
|
||||
VertexDeclHandle findVertexDecl(const VertexDecl& _decl)
|
||||
@ -2319,10 +2359,11 @@ namespace bgfx
|
||||
BGFX_API_FUNC(void destroyVertexBuffer(VertexBufferHandle _handle) )
|
||||
{
|
||||
BGFX_CHECK_HANDLE("destroyVertexBuffer", m_vertexBufferHandle, _handle);
|
||||
bool ok = m_submit->free(_handle); BX_UNUSED(ok);
|
||||
BX_CHECK(ok, "Vertex buffer handle %d is already destroyed!", _handle.idx);
|
||||
|
||||
CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyVertexBuffer);
|
||||
cmdbuf.write(_handle);
|
||||
m_submit->free(_handle);
|
||||
}
|
||||
|
||||
void destroyVertexBufferInternal(VertexBufferHandle _handle)
|
||||
@ -2978,9 +3019,11 @@ namespace bgfx
|
||||
int32_t refs = --sr.m_refCount;
|
||||
if (0 == refs)
|
||||
{
|
||||
bool ok = m_submit->free(_handle); BX_UNUSED(ok);
|
||||
BX_CHECK(ok, "Shader handle %d is already destroyed!", _handle.idx);
|
||||
|
||||
CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyShader);
|
||||
cmdbuf.write(_handle);
|
||||
m_submit->free(_handle);
|
||||
|
||||
if (0 != sr.m_num)
|
||||
{
|
||||
@ -3060,7 +3103,7 @@ namespace bgfx
|
||||
{
|
||||
if (!isValid(_vsh) )
|
||||
{
|
||||
BX_WARN(false, "Vertex/fragment shader is invalid (vsh %d).", _vsh.idx);
|
||||
BX_WARN(false, "Compute shader is invalid (vsh %d).", _vsh.idx);
|
||||
ProgramHandle invalid = BGFX_INVALID_HANDLE;
|
||||
return invalid;
|
||||
}
|
||||
@ -3113,9 +3156,11 @@ namespace bgfx
|
||||
int32_t refs = --pr.m_refCount;
|
||||
if (0 == refs)
|
||||
{
|
||||
bool ok = m_submit->free(_handle); BX_UNUSED(ok);
|
||||
BX_CHECK(ok, "Program handle %d is already destroyed!", _handle.idx);
|
||||
|
||||
CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyProgram);
|
||||
cmdbuf.write(_handle);
|
||||
m_submit->free(_handle);
|
||||
|
||||
shaderDecRef(pr.m_vsh);
|
||||
uint32_t hash = pr.m_vsh.idx;
|
||||
@ -3266,9 +3311,11 @@ namespace bgfx
|
||||
int32_t refs = --ref.m_refCount;
|
||||
if (0 == refs)
|
||||
{
|
||||
bool ok = m_submit->free(_handle); BX_UNUSED(ok);
|
||||
BX_CHECK(ok, "Texture handle %d is already destroyed!", _handle.idx);
|
||||
|
||||
CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyTexture);
|
||||
cmdbuf.write(_handle);
|
||||
m_submit->free(_handle);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3398,10 +3445,11 @@ namespace bgfx
|
||||
BGFX_API_FUNC(void destroyFrameBuffer(FrameBufferHandle _handle) )
|
||||
{
|
||||
BGFX_CHECK_HANDLE("destroyFrameBuffer", m_frameBufferHandle, _handle);
|
||||
bool ok = m_submit->free(_handle); BX_UNUSED(ok);
|
||||
BX_CHECK(ok, "Frame buffer handle %d is already destroyed!", _handle.idx);
|
||||
|
||||
CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyFrameBuffer);
|
||||
cmdbuf.write(_handle);
|
||||
m_submit->free(_handle);
|
||||
|
||||
FrameBufferRef& ref = m_frameBufferRef[_handle.idx];
|
||||
if (!ref.m_window)
|
||||
@ -3510,12 +3558,14 @@ namespace bgfx
|
||||
|
||||
if (0 == refs)
|
||||
{
|
||||
bool ok = m_submit->free(_handle); BX_UNUSED(ok);
|
||||
BX_CHECK(ok, "Uniform handle %d is already destroyed!", _handle.idx);
|
||||
|
||||
uniform.m_name.clear();
|
||||
m_uniformHashMap.removeByHandle(_handle.idx);
|
||||
|
||||
CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyUniform);
|
||||
cmdbuf.write(_handle);
|
||||
m_submit->free(_handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user