Cache applied vertex buffers and input layout.
Issue #451
Signed-off-by: Jamie Madill
Signed-off-by: Shannon Woods
Author: Geoff Lang
diff --git a/src/libGLESv2/renderer/InputLayoutCache.cpp b/src/libGLESv2/renderer/InputLayoutCache.cpp
index 0402bb3..fcc6f7c 100644
--- a/src/libGLESv2/renderer/InputLayoutCache.cpp
+++ b/src/libGLESv2/renderer/InputLayoutCache.cpp
@@ -28,6 +28,13 @@
mCounter = 0;
mDevice = NULL;
mDeviceContext = NULL;
+ mCurrentIL = NULL;
+ for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
+ {
+ mCurrentBuffers[i] = -1;
+ mCurrentVertexStrides[i] = -1;
+ mCurrentVertexOffsets[i] = -1;
+ }
}
InputLayoutCache::~InputLayoutCache()
@@ -49,6 +56,18 @@
i->second.inputLayout->Release();
}
mInputLayoutMap.clear();
+ markDirty();
+}
+
+void InputLayoutCache::markDirty()
+{
+ mCurrentIL = NULL;
+ for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
+ {
+ mCurrentBuffers[i] = -1;
+ mCurrentVertexStrides[i] = -1;
+ mCurrentVertexOffsets[i] = -1;
+ }
}
GLenum InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS],
@@ -66,6 +85,7 @@
InputLayoutKey ilKey = { 0 };
ID3D11Buffer *vertexBuffers[gl::MAX_VERTEX_ATTRIBS] = { NULL };
+ unsigned int vertexBufferSerials[gl::MAX_VERTEX_ATTRIBS] = { 0 };
UINT vertexStrides[gl::MAX_VERTEX_ATTRIBS] = { 0 };
UINT vertexOffsets[gl::MAX_VERTEX_ATTRIBS] = { 0 };
@@ -95,6 +115,7 @@
ilKey.elementCount++;
vertexBuffers[i] = bufferStorage ? bufferStorage->getBuffer() : vertexBuffer->getBuffer();
+ vertexBufferSerials[i] = bufferStorage ? bufferStorage->getSerial() : vertexBuffer->getSerial();
vertexStrides[i] = attributes[i].stride;
vertexOffsets[i] = attributes[i].offset;
}
@@ -143,8 +164,23 @@
mInputLayoutMap.insert(std::make_pair(ilKey, inputCounterPair));
}
- mDeviceContext->IASetInputLayout(inputLayout);
- mDeviceContext->IASetVertexBuffers(0, gl::MAX_VERTEX_ATTRIBS, vertexBuffers, vertexStrides, vertexOffsets);
+ if (inputLayout != mCurrentIL)
+ {
+ mDeviceContext->IASetInputLayout(inputLayout);
+ mCurrentIL = inputLayout;
+ }
+
+ for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
+ {
+ if (vertexBufferSerials[i] != mCurrentBuffers[i] || vertexStrides[i] != mCurrentVertexStrides[i] ||
+ vertexOffsets[i] != mCurrentVertexOffsets[i])
+ {
+ mDeviceContext->IASetVertexBuffers(i, 1, &vertexBuffers[i], &vertexStrides[i], &vertexOffsets[i]);
+ mCurrentBuffers[i] = vertexBufferSerials[i];
+ mCurrentVertexStrides[i] = vertexStrides[i];
+ mCurrentVertexOffsets[i] = vertexOffsets[i];
+ }
+ }
return GL_NO_ERROR;
}
diff --git a/src/libGLESv2/renderer/InputLayoutCache.h b/src/libGLESv2/renderer/InputLayoutCache.h
index d95f39f..797853d 100644
--- a/src/libGLESv2/renderer/InputLayoutCache.h
+++ b/src/libGLESv2/renderer/InputLayoutCache.h
@@ -30,6 +30,7 @@
void initialize(ID3D11Device *device, ID3D11DeviceContext *context);
void clear();
+ void markDirty();
GLenum applyVertexBuffers(TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS],
gl::ProgramBinary *programBinary);
@@ -50,6 +51,11 @@
unsigned long long lastUsedTime;
};
+ ID3D11InputLayout *mCurrentIL;
+ unsigned int mCurrentBuffers[gl::MAX_VERTEX_ATTRIBS];
+ UINT mCurrentVertexStrides[gl::MAX_VERTEX_ATTRIBS];
+ UINT mCurrentVertexOffsets[gl::MAX_VERTEX_ATTRIBS];
+
static std::size_t hashInputLayout(const InputLayoutKey &inputLayout);
static bool compareInputLayouts(const InputLayoutKey &a, const InputLayoutKey &b);
diff --git a/src/libGLESv2/renderer/Renderer11.cpp b/src/libGLESv2/renderer/Renderer11.cpp
index e544b40..c0066d0 100644
--- a/src/libGLESv2/renderer/Renderer11.cpp
+++ b/src/libGLESv2/renderer/Renderer11.cpp
@@ -1797,6 +1797,8 @@
mAppliedProgramBinarySerial = 0;
memset(&mAppliedVertexConstants, 0, sizeof(dx_VertexConstants));
memset(&mAppliedPixelConstants, 0, sizeof(dx_PixelConstants));
+
+ mInputLayoutCache.markDirty();
}
void Renderer11::releaseDeviceResources()