mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-15 11:06:54 +00:00
213 lines
6.2 KiB
C++
213 lines
6.2 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 "driver/gl/gl_manager.h"
|
|
#include "driver/gl/gl_driver.h"
|
|
|
|
struct VertexArrayInitialData
|
|
{
|
|
VertexArrayInitialData()
|
|
{
|
|
RDCEraseEl(*this);
|
|
}
|
|
uint32_t enabled;
|
|
uint32_t vbslot;
|
|
uint32_t offset;
|
|
GLenum type;
|
|
int32_t normalized;
|
|
uint32_t integer;
|
|
uint32_t size;
|
|
};
|
|
|
|
bool GLResourceManager::SerialisableResource(ResourceId id, GLResourceRecord *record)
|
|
{
|
|
if(id == m_GL->GetContextResourceID())
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
bool GLResourceManager::Need_InitialStateChunk(GLResource res)
|
|
{
|
|
return res.Namespace != eResBuffer;
|
|
}
|
|
|
|
bool GLResourceManager::Prepare_InitialState(GLResource res)
|
|
{
|
|
ResourceId Id = GetID(res);
|
|
|
|
if(res.Namespace == eResBuffer)
|
|
{
|
|
GLResourceRecord *record = GetResourceRecord(res);
|
|
|
|
// TODO copy this to an immutable buffer elsewhere and SetInitialContents() it.
|
|
// then only do the readback in Serialise_InitialState
|
|
|
|
GLint length;
|
|
m_GL->glGetNamedBufferParameterivEXT(res.name, eGL_BUFFER_SIZE, &length);
|
|
|
|
m_GL->glGetNamedBufferSubDataEXT(res.name, 0, length, record->GetDataPtr());
|
|
}
|
|
else if(res.Namespace == eResVertexArray)
|
|
{
|
|
GLuint VAO = 0;
|
|
m_GL->glGetIntegerv(eGL_VERTEX_ARRAY_BINDING, (GLint *)&VAO);
|
|
|
|
m_GL->glBindVertexArray(res.name);
|
|
|
|
VertexArrayInitialData *data = (VertexArrayInitialData *)new byte[sizeof(VertexArrayInitialData)*16];
|
|
|
|
for(GLuint i=0; i < 16; i++)
|
|
{
|
|
m_GL->glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_ENABLED, (GLint *)&data[i].enabled);
|
|
m_GL->glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_BINDING, (GLint *)&data[i].vbslot);
|
|
m_GL->glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_RELATIVE_OFFSET, (GLint*)&data[i].offset);
|
|
m_GL->glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_TYPE, (GLint *)&data[i].type);
|
|
m_GL->glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_NORMALIZED, (GLint *)&data[i].normalized);
|
|
m_GL->glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_INTEGER, (GLint *)&data[i].integer);
|
|
m_GL->glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_SIZE, (GLint *)&data[i].size);
|
|
}
|
|
|
|
SetInitialContents(Id, InitialContentData(GLResource(MakeNullResource), 0, (byte *)data));
|
|
|
|
m_GL->glBindVertexArray(VAO);
|
|
}
|
|
else
|
|
{
|
|
RDCERR("Unexpected type of resource requiring initial state");
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool GLResourceManager::Force_InitialState(GLResource res)
|
|
{
|
|
// hack for now, these should be tracked through the normal dirty/ref tracking process.
|
|
if(res.Namespace == eResVertexArray) return true;
|
|
return false;
|
|
}
|
|
|
|
bool GLResourceManager::Serialise_InitialState(GLResource res)
|
|
{
|
|
ResourceId Id = ResourceId();
|
|
|
|
if(m_State >= WRITING)
|
|
{
|
|
Id = GetID(res);
|
|
|
|
if(res.Namespace != eResBuffer)
|
|
m_pSerialiser->Serialise("Id", Id);
|
|
}
|
|
else
|
|
{
|
|
m_pSerialiser->Serialise("Id", Id);
|
|
}
|
|
|
|
if(m_State < WRITING)
|
|
{
|
|
if(HasLiveResource(Id))
|
|
res = GetLiveResource(Id);
|
|
else
|
|
res = GLResource(MakeNullResource);
|
|
}
|
|
|
|
if(res.Namespace == eResVertexArray)
|
|
{
|
|
VertexArrayInitialData data[16];
|
|
|
|
if(m_State >= WRITING)
|
|
{
|
|
VertexArrayInitialData *initialdata = (VertexArrayInitialData *)GetInitialContents(Id).blob;
|
|
memcpy(data, initialdata, sizeof(data));
|
|
}
|
|
|
|
for(GLuint i=0; i < 16; i++)
|
|
{
|
|
m_pSerialiser->Serialise("data[].enabled", data[i].enabled);
|
|
m_pSerialiser->Serialise("data[].vbslot", data[i].vbslot);
|
|
m_pSerialiser->Serialise("data[].offset", data[i].offset);
|
|
m_pSerialiser->Serialise("data[].type", data[i].type);
|
|
m_pSerialiser->Serialise("data[].normalized", data[i].normalized);
|
|
m_pSerialiser->Serialise("data[].integer", data[i].integer);
|
|
m_pSerialiser->Serialise("data[].size", data[i].size);
|
|
}
|
|
|
|
if(m_State < WRITING)
|
|
{
|
|
byte *blob = new byte[sizeof(data)];
|
|
memcpy(blob, data, sizeof(data));
|
|
|
|
SetInitialContents(Id, InitialContentData(GLResource(MakeNullResource), 0, blob));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
RDCERR("Unexpected type of resource requiring initial state");
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void GLResourceManager::Create_InitialState(ResourceId id, GLResource live, bool hasData)
|
|
{
|
|
if(live.Namespace != eResBuffer)
|
|
{
|
|
RDCUNIMPLEMENTED("Expect all initial states to be created & not skipped, presently");
|
|
}
|
|
}
|
|
|
|
void GLResourceManager::Apply_InitialState(GLResource live, InitialContentData initial)
|
|
{
|
|
if(live.Namespace == eResVertexArray)
|
|
{
|
|
GLuint VAO = 0;
|
|
m_GL->glGetIntegerv(eGL_VERTEX_ARRAY_BINDING, (GLint *)&VAO);
|
|
|
|
m_GL->glBindVertexArray(live.name);
|
|
|
|
VertexArrayInitialData *initialdata = (VertexArrayInitialData *)initial.blob;
|
|
|
|
for(GLuint i=0; i < 16; i++)
|
|
{
|
|
if(initialdata[i].enabled)
|
|
m_GL->glEnableVertexAttribArray(i);
|
|
else
|
|
m_GL->glDisableVertexAttribArray(i);
|
|
|
|
m_GL->glVertexAttribBinding(i, initialdata[i].vbslot);
|
|
|
|
if(initialdata[i].integer == 0)
|
|
m_GL->glVertexAttribFormat(i, initialdata[i].size, initialdata[i].type, (GLboolean)initialdata[i].normalized, initialdata[i].offset);
|
|
else
|
|
m_GL->glVertexAttribIFormat(i, initialdata[i].size, initialdata[i].type, initialdata[i].offset);
|
|
}
|
|
|
|
m_GL->glBindVertexArray(VAO);
|
|
}
|
|
else
|
|
{
|
|
RDCERR("Unexpected type of resource requiring initial state");
|
|
}
|
|
}
|