mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-14 05:50:51 +00:00
With some regret, add hack on AMD to not use VERTEX_BINDING_BUFFER
* AMD drivers (at least on linux, haven't tested windows) don't recognise VERTEX_BINDING_BUFFER, so instead we create a dummy VAO with each attrib bound to the corresponding buffer and then use VERTEX_ATTRIB_ARRAY_BUFFER_BINDING to query the buffer out.
This commit is contained in:
@@ -93,13 +93,52 @@ void GLRenderState::FetchState()
|
||||
m_Real->glActiveTexture(ActiveTexture);
|
||||
|
||||
m_Real->glGetIntegerv(eGL_VERTEX_ARRAY_BINDING, (GLint *)&VAO);
|
||||
for(GLuint i=0; i < (GLuint)ARRAY_COUNT(VertexBuffers); i++)
|
||||
{
|
||||
m_Real->glGetIntegeri_v(eGL_VERTEX_BINDING_BUFFER, i, (GLint *)&VertexBuffers[i].Buffer);
|
||||
|
||||
static int hackAMDBugVBBinding = -1;
|
||||
|
||||
m_Real->glGetIntegeri_v(eGL_VERTEX_BINDING_STRIDE, i, (GLint *)&VertexBuffers[i].Stride);
|
||||
m_Real->glGetIntegeri_v(eGL_VERTEX_BINDING_OFFSET, i, (GLint *)&VertexBuffers[i].Offset);
|
||||
m_Real->glGetIntegeri_v(eGL_VERTEX_BINDING_DIVISOR, i, (GLint *)&VertexBuffers[i].Divisor);
|
||||
if(hackAMDBugVBBinding == -1)
|
||||
{
|
||||
GLenum err = m_Real->glGetError();
|
||||
while(err != eGL_NONE) err = m_Real->glGetError();
|
||||
GLint dummy = 0;
|
||||
m_Real->glGetIntegeri_v(eGL_VERTEX_BINDING_BUFFER, 0, &dummy);
|
||||
err = m_Real->glGetError();
|
||||
|
||||
hackAMDBugVBBinding = (err == eGL_NONE ? 0 : 1);
|
||||
|
||||
if(hackAMDBugVBBinding)
|
||||
RDCWARN("Using AMD hack to avoid GL_VERTEX_BINDING_BUFFER");
|
||||
}
|
||||
|
||||
if(VAO != 0)
|
||||
{
|
||||
GLuint hackVAO = 0;
|
||||
if(hackAMDBugVBBinding)
|
||||
{
|
||||
// create 'pass through' VAO so we can use GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING to fetch buffers
|
||||
m_Real->glGenVertexArrays(1, &hackVAO);
|
||||
m_Real->glBindVertexArray(hackVAO);
|
||||
for(GLuint i=0; i < (GLuint)ARRAY_COUNT(VertexBuffers); i++)
|
||||
m_Real->glVertexAttribBinding(i, i);
|
||||
}
|
||||
|
||||
for(GLuint i=0; i < (GLuint)ARRAY_COUNT(VertexBuffers); i++)
|
||||
{
|
||||
if(hackAMDBugVBBinding)
|
||||
m_Real->glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, (GLint *)&VertexBuffers[i].Buffer);
|
||||
else
|
||||
m_Real->glGetIntegeri_v(eGL_VERTEX_BINDING_BUFFER, i, (GLint *)&VertexBuffers[i].Buffer);
|
||||
|
||||
m_Real->glGetIntegeri_v(eGL_VERTEX_BINDING_STRIDE, i, (GLint *)&VertexBuffers[i].Stride);
|
||||
m_Real->glGetIntegeri_v(eGL_VERTEX_BINDING_OFFSET, i, (GLint *)&VertexBuffers[i].Offset);
|
||||
m_Real->glGetIntegeri_v(eGL_VERTEX_BINDING_DIVISOR, i, (GLint *)&VertexBuffers[i].Divisor);
|
||||
}
|
||||
|
||||
if(hackAMDBugVBBinding)
|
||||
{
|
||||
m_Real->glBindVertexArray(VAO);
|
||||
m_Real->glDeleteVertexArrays(1, &hackVAO);
|
||||
}
|
||||
}
|
||||
|
||||
// the spec says that you can only query for the format that was previously set, or you get
|
||||
@@ -238,9 +277,11 @@ void GLRenderState::FetchState()
|
||||
m_Real->glGetFloatv(eGL_PATCH_DEFAULT_OUTER_LEVEL, &PatchParams.defaultOuterLevel[0]);
|
||||
|
||||
{
|
||||
GLenum dummy[2];
|
||||
// docs suggest this is enumeration[2] even though polygon mode can't be set independently for front
|
||||
// and back faces.
|
||||
// This was listed in docs as enumeration[2] even though polygon mode can't be set independently for front
|
||||
// and back faces for a while, so pass large enough array to be sure.
|
||||
// AMD driver claims this doesn't exist anymore in core, so don't return any value, set to
|
||||
// default GL_FILL to be safe
|
||||
GLenum dummy[2] = { eGL_FILL, eGL_FILL };
|
||||
m_Real->glGetIntegerv(eGL_POLYGON_MODE, (GLint *)&dummy);
|
||||
PolygonMode = dummy[0];
|
||||
}
|
||||
@@ -301,10 +342,13 @@ void GLRenderState::ApplyState()
|
||||
m_Real->glActiveTexture(ActiveTexture);
|
||||
|
||||
m_Real->glBindVertexArray(VAO);
|
||||
for(GLuint i=0; i < (GLuint)ARRAY_COUNT(VertexBuffers); i++)
|
||||
if(VAO != 0)
|
||||
{
|
||||
m_Real->glBindVertexBuffer(i, VertexBuffers[i].Buffer, (GLintptr)VertexBuffers[i].Offset, (GLsizei)VertexBuffers[i].Stride);
|
||||
m_Real->glVertexBindingDivisor(i, VertexBuffers[i].Divisor);
|
||||
for(GLuint i=0; i < (GLuint)ARRAY_COUNT(VertexBuffers); i++)
|
||||
{
|
||||
m_Real->glBindVertexBuffer(i, VertexBuffers[i].Buffer, (GLintptr)VertexBuffers[i].Offset, (GLsizei)VertexBuffers[i].Stride);
|
||||
m_Real->glVertexBindingDivisor(i, VertexBuffers[i].Divisor);
|
||||
}
|
||||
}
|
||||
|
||||
// See FetchState(). The spec says that you have to SET the right format for the shader too,
|
||||
|
||||
@@ -796,13 +796,11 @@ void GLReplay::SavePipelineState()
|
||||
|
||||
for(GLuint i=0; i < (GLuint)numVBufferBindings; i++)
|
||||
{
|
||||
GLint vb = 0;
|
||||
gl.glGetIntegeri_v(eGL_VERTEX_BINDING_BUFFER, i, &vb);
|
||||
pipe.m_VtxIn.vbuffers[i].Buffer = rm->GetOriginalID(rm->GetID(BufferRes(ctx, vb)));
|
||||
pipe.m_VtxIn.vbuffers[i].Buffer = rm->GetOriginalID(rm->GetID(BufferRes(ctx, rs.VertexBuffers[i].Buffer)));
|
||||
|
||||
gl.glGetIntegeri_v(eGL_VERTEX_BINDING_STRIDE, i, (GLint *)&pipe.m_VtxIn.vbuffers[i].Stride);
|
||||
gl.glGetIntegeri_v(eGL_VERTEX_BINDING_OFFSET, i, (GLint *)&pipe.m_VtxIn.vbuffers[i].Offset);
|
||||
gl.glGetIntegeri_v(eGL_VERTEX_BINDING_DIVISOR, i, (GLint *)&pipe.m_VtxIn.vbuffers[i].Divisor);
|
||||
pipe.m_VtxIn.vbuffers[i].Stride = (uint32_t)rs.VertexBuffers[i].Stride;
|
||||
pipe.m_VtxIn.vbuffers[i].Offset = (uint32_t)rs.VertexBuffers[i].Offset;
|
||||
pipe.m_VtxIn.vbuffers[i].Divisor = rs.VertexBuffers[i].Divisor;
|
||||
pipe.m_VtxIn.vbuffers[i].PerInstance = (pipe.m_VtxIn.vbuffers[i].Divisor != 0);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user