Commit e18eb970 by Jamie Madill Committed by Commit Bot

D3D: Refactor VertexDataManager attribute storage.

Instead of splitting attributes into 'active enabled' and 'active disabled', split them into static/dynamic/direct/current value, and handle each group invidually. This also will allow the dirty bits code to call in to the VertexDataManager separately for each type of necessary vertex data translation, and skip it entirely for direct buffer storage. Should be a refactoring patch only. BUG=angleproject:1327 Change-Id: I53cb5672054d99ae68e9aa2e5a3c046a002e360d Reviewed-on: https://chromium-review.googlesource.com/330171Reviewed-by: 's avatarZhenyao Mo <zmo@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent e36b92d4
...@@ -26,7 +26,7 @@ BufferD3D::BufferD3D(BufferFactoryD3D *factory) ...@@ -26,7 +26,7 @@ BufferD3D::BufferD3D(BufferFactoryD3D *factory)
mStaticBufferCacheTotalSize(0), mStaticBufferCacheTotalSize(0),
mStaticVertexBufferOutOfDate(false), mStaticVertexBufferOutOfDate(false),
mUnmodifiedDataUse(0), mUnmodifiedDataUse(0),
mUsage(D3D_BUFFER_USAGE_STATIC) mUsage(D3DBufferUsage::STATIC)
{ {
updateSerial(); updateSerial();
} }
...@@ -54,7 +54,7 @@ void BufferD3D::updateD3DBufferUsage(GLenum usage) ...@@ -54,7 +54,7 @@ void BufferD3D::updateD3DBufferUsage(GLenum usage)
case GL_STATIC_DRAW: case GL_STATIC_DRAW:
case GL_STATIC_READ: case GL_STATIC_READ:
case GL_STATIC_COPY: case GL_STATIC_COPY:
mUsage = D3D_BUFFER_USAGE_STATIC; mUsage = D3DBufferUsage::STATIC;
initializeStaticData(); initializeStaticData();
break; break;
...@@ -64,7 +64,7 @@ void BufferD3D::updateD3DBufferUsage(GLenum usage) ...@@ -64,7 +64,7 @@ void BufferD3D::updateD3DBufferUsage(GLenum usage)
case GL_DYNAMIC_READ: case GL_DYNAMIC_READ:
case GL_DYNAMIC_COPY: case GL_DYNAMIC_COPY:
case GL_DYNAMIC_DRAW: case GL_DYNAMIC_DRAW:
mUsage = D3D_BUFFER_USAGE_DYNAMIC; mUsage = D3DBufferUsage::DYNAMIC;
break; break;
default: default:
UNREACHABLE(); UNREACHABLE();
...@@ -150,7 +150,7 @@ void BufferD3D::invalidateStaticData() ...@@ -150,7 +150,7 @@ void BufferD3D::invalidateStaticData()
// If the buffer was created with a static usage then we recreate the static // If the buffer was created with a static usage then we recreate the static
// buffers so that they are populated the next time we use this buffer. // buffers so that they are populated the next time we use this buffer.
if (mUsage == D3D_BUFFER_USAGE_STATIC) if (mUsage == D3DBufferUsage::STATIC)
{ {
initializeStaticData(); initializeStaticData();
} }
......
...@@ -21,10 +21,10 @@ class BufferFactoryD3D; ...@@ -21,10 +21,10 @@ class BufferFactoryD3D;
class StaticIndexBufferInterface; class StaticIndexBufferInterface;
class StaticVertexBufferInterface; class StaticVertexBufferInterface;
enum D3DBufferUsage enum class D3DBufferUsage
{ {
D3D_BUFFER_USAGE_STATIC, STATIC,
D3D_BUFFER_USAGE_DYNAMIC, DYNAMIC,
}; };
class BufferD3D : public BufferImpl class BufferD3D : public BufferImpl
...@@ -55,6 +55,7 @@ class BufferD3D : public BufferImpl ...@@ -55,6 +55,7 @@ class BufferD3D : public BufferImpl
gl::IndexRange *outRange) override; gl::IndexRange *outRange) override;
BufferFactoryD3D *getFactory() const { return mFactory; } BufferFactoryD3D *getFactory() const { return mFactory; }
D3DBufferUsage getUsage() const { return mUsage; }
protected: protected:
void updateSerial(); void updateSerial();
......
...@@ -114,6 +114,42 @@ TranslatedAttribute::TranslatedAttribute() ...@@ -114,6 +114,42 @@ TranslatedAttribute::TranslatedAttribute()
{ {
} }
VertexStorageType ClassifyAttributeStorage(const gl::VertexAttribute &attrib)
{
// If attribute is disabled, we use the current value.
if (!attrib.enabled)
{
return VertexStorageType::CURRENT_VALUE;
}
// If specified with immediate data, we must use dynamic storage.
auto *buffer = attrib.buffer.get();
if (!buffer)
{
return VertexStorageType::DYNAMIC;
}
// Check if the buffer supports direct storage.
if (DirectStoragePossible(attrib))
{
return VertexStorageType::DIRECT;
}
// Otherwise the storage is static or dynamic.
BufferD3D *bufferD3D = GetImplAs<BufferD3D>(buffer);
ASSERT(bufferD3D);
switch (bufferD3D->getUsage())
{
case D3DBufferUsage::DYNAMIC:
return VertexStorageType::DYNAMIC;
case D3DBufferUsage::STATIC:
return VertexStorageType::STATIC;
default:
UNREACHABLE();
return VertexStorageType::UNKNOWN;
}
}
VertexDataManager::CurrentValueState::CurrentValueState() VertexDataManager::CurrentValueState::CurrentValueState()
: buffer(nullptr), : buffer(nullptr),
offset(0) offset(0)
...@@ -142,10 +178,6 @@ VertexDataManager::VertexDataManager(BufferFactoryD3D *factory) ...@@ -142,10 +178,6 @@ VertexDataManager::VertexDataManager(BufferFactoryD3D *factory)
{ {
ERR("Failed to allocate the streaming vertex buffer."); ERR("Failed to allocate the streaming vertex buffer.");
} }
// TODO(jmadill): use context caps
mActiveEnabledAttributes.reserve(gl::MAX_VERTEX_ATTRIBS);
mActiveDisabledAttributes.reserve(gl::MAX_VERTEX_ATTRIBS);
} }
VertexDataManager::~VertexDataManager() VertexDataManager::~VertexDataManager()
...@@ -164,100 +196,213 @@ gl::Error VertexDataManager::prepareVertexData(const gl::State &state, ...@@ -164,100 +196,213 @@ gl::Error VertexDataManager::prepareVertexData(const gl::State &state,
std::vector<TranslatedAttribute> *translatedAttribs, std::vector<TranslatedAttribute> *translatedAttribs,
GLsizei instances) GLsizei instances)
{ {
if (!mStreamingBuffer) ASSERT(mStreamingBuffer);
{
return gl::Error(GL_OUT_OF_MEMORY, "Internal streaming vertex buffer is unexpectedly NULL.");
}
// Compute active enabled and active disable attributes, for speed.
// TODO(jmadill): don't recompute if there was no state change
const gl::VertexArray *vertexArray = state.getVertexArray(); const gl::VertexArray *vertexArray = state.getVertexArray();
const gl::Program *program = state.getProgram();
const auto &vertexAttributes = vertexArray->getVertexAttributes(); const auto &vertexAttributes = vertexArray->getVertexAttributes();
mActiveEnabledAttributes.clear(); mDynamicAttributeIndexesCache.clear();
mActiveDisabledAttributes.clear(); const gl::Program *program = state.getProgram();
translatedAttribs->clear(); translatedAttribs->clear();
for (size_t attribIndex = 0; attribIndex < vertexAttributes.size(); ++attribIndex) for (size_t attribIndex = 0; attribIndex < vertexAttributes.size(); ++attribIndex)
{ {
if (program->isAttribLocationActive(attribIndex)) // Skip attrib locations the program doesn't use.
{ if (!program->isAttribLocationActive(attribIndex))
// Resize automatically puts in empty attribs continue;
translatedAttribs->resize(attribIndex + 1);
const auto &attrib = vertexAttributes[attribIndex];
TranslatedAttribute *translated = &(*translatedAttribs)[attribIndex]; // Resize automatically puts in empty attribs
translatedAttribs->resize(attribIndex + 1);
// Record the attribute now TranslatedAttribute *translated = &(*translatedAttribs)[attribIndex];
translated->active = true; auto currentValueData =
translated->attribute = &vertexAttributes[attribIndex]; state.getVertexAttribCurrentValue(static_cast<unsigned int>(attribIndex));
translated->currentValueType =
state.getVertexAttribCurrentValue(static_cast<unsigned int>(attribIndex)).Type;
translated->divisor = vertexAttributes[attribIndex].divisor;
if (vertexAttributes[attribIndex].enabled) // Record the attribute now
translated->active = true;
translated->attribute = &attrib;
translated->currentValueType = currentValueData.Type;
translated->divisor = attrib.divisor;
switch (ClassifyAttributeStorage(attrib))
{
case VertexStorageType::STATIC:
{ {
mActiveEnabledAttributes.push_back(translated); // Store static attribute.
gl::Error error = StoreStaticAttrib(translated, start, count, instances);
if (error.isError())
{
return error;
}
break;
} }
else case VertexStorageType::DYNAMIC:
// Dynamic attributes must be handled together.
mDynamicAttributeIndexesCache.push_back(attribIndex);
break;
case VertexStorageType::DIRECT:
// Update translated data for direct attributes.
StoreDirectAttrib(translated, start);
break;
case VertexStorageType::CURRENT_VALUE:
{ {
mActiveDisabledAttributes.push_back(attribIndex); gl::Error error = storeCurrentValue(currentValueData, translated, attribIndex);
if (error.isError())
{
return error;
}
break;
} }
default:
UNREACHABLE();
break;
} }
} }
// Reserve the required space in the buffers if (mDynamicAttributeIndexesCache.empty())
for (const TranslatedAttribute *activeAttrib : mActiveEnabledAttributes)
{ {
gl::Error error = reserveSpaceForAttrib(*activeAttrib, count, instances); gl::Error(GL_NO_ERROR);
if (error.isError()) }
{
return error; return storeDynamicAttribs(translatedAttribs, mDynamicAttributeIndexesCache, start, count,
} instances);
}
// static
void VertexDataManager::StoreDirectAttrib(TranslatedAttribute *directAttrib, GLint start)
{
const auto &attrib = *directAttrib->attribute;
gl::Buffer *buffer = attrib.buffer.get();
BufferD3D *bufferD3D = buffer ? GetImplAs<BufferD3D>(buffer) : nullptr;
// Instanced vertices do not apply the 'start' offset
GLint firstVertexIndex = (attrib.divisor > 0 ? 0 : start);
ASSERT(DirectStoragePossible(attrib));
directAttrib->vertexBuffer.set(nullptr);
directAttrib->storage = bufferD3D;
directAttrib->serial = bufferD3D->getSerial();
directAttrib->stride = static_cast<unsigned int>(ComputeVertexAttributeStride(attrib));
directAttrib->offset =
static_cast<unsigned int>(attrib.offset + directAttrib->stride * firstVertexIndex);
}
// static
gl::Error VertexDataManager::StoreStaticAttrib(TranslatedAttribute *translated,
GLint start,
GLsizei count,
GLsizei instances)
{
const gl::VertexAttribute &attrib = *translated->attribute;
gl::Buffer *buffer = attrib.buffer.get();
ASSERT(buffer && attrib.enabled && !DirectStoragePossible(attrib));
BufferD3D *bufferD3D = GetImplAs<BufferD3D>(buffer);
// Instanced vertices do not apply the 'start' offset
GLint firstVertexIndex = (attrib.divisor > 0 ? 0 : start);
// Compute source data pointer
const uint8_t *sourceData = nullptr;
gl::Error error = bufferD3D->getData(&sourceData);
if (error.isError())
{
return error;
}
sourceData += static_cast<int>(attrib.offset);
unsigned int streamOffset = 0;
auto errorOrOutputElementSize = bufferD3D->getFactory()->getVertexSpaceRequired(attrib, 1, 0);
if (errorOrOutputElementSize.isError())
{
return errorOrOutputElementSize.getError();
} }
// Perform the vertex data translations translated->storage = nullptr;
for (TranslatedAttribute *activeAttrib : mActiveEnabledAttributes) translated->stride = errorOrOutputElementSize.getResult();
auto *staticBuffer = bufferD3D->getStaticVertexBuffer(attrib);
ASSERT(staticBuffer);
if (staticBuffer->empty())
{ {
gl::Error error = storeAttribute(activeAttrib, start, count, instances); // Convert the entire buffer
int totalCount = ElementsInBuffer(attrib, static_cast<unsigned int>(bufferD3D->getSize()));
int startIndex = static_cast<int>(attrib.offset) /
static_cast<int>(ComputeVertexAttributeStride(attrib));
error = staticBuffer->storeStaticAttribute(attrib, -startIndex, totalCount, 0, sourceData);
if (error.isError()) if (error.isError())
{ {
unmapStreamingBuffer();
return error; return error;
} }
} }
unmapStreamingBuffer(); unsigned int firstElementOffset =
(static_cast<unsigned int>(attrib.offset) /
for (size_t attribIndex : mActiveDisabledAttributes) static_cast<unsigned int>(ComputeVertexAttributeStride(attrib))) *
translated->stride;
ASSERT(attrib.divisor == 0 || firstVertexIndex == 0);
unsigned int startOffset = firstVertexIndex * translated->stride;
if (streamOffset + firstElementOffset + startOffset < streamOffset)
{ {
if (mCurrentValueCache[attribIndex].buffer == nullptr) return gl::Error(GL_OUT_OF_MEMORY);
{ }
mCurrentValueCache[attribIndex].buffer = new StreamingVertexBufferInterface(mFactory, CONSTANT_VERTEX_BUFFER_SIZE);
}
gl::Error error = storeCurrentValue( VertexBuffer *vertexBuffer = staticBuffer->getVertexBuffer();
state.getVertexAttribCurrentValue(static_cast<unsigned int>(attribIndex)),
&(*translatedAttribs)[attribIndex], &mCurrentValueCache[attribIndex]); translated->vertexBuffer.set(vertexBuffer);
translated->serial = vertexBuffer->getSerial();
translated->offset = streamOffset + firstElementOffset + startOffset;
return gl::Error(GL_NO_ERROR);
}
gl::Error VertexDataManager::storeDynamicAttribs(
std::vector<TranslatedAttribute> *translatedAttribs,
const std::vector<size_t> &dynamicAttribIndexes,
GLint start,
GLsizei count,
GLsizei instances)
{
// Reserve the required space for the dynamic buffers.
for (size_t attribIndex : dynamicAttribIndexes)
{
const auto &dynamicAttrib = (*translatedAttribs)[attribIndex];
gl::Error error = reserveSpaceForAttrib(dynamicAttrib, count, instances);
if (error.isError()) if (error.isError())
{ {
return error; return error;
} }
} }
for (const TranslatedAttribute *activeAttrib : mActiveEnabledAttributes) // Store dynamic attributes
for (size_t attribIndex : dynamicAttribIndexes)
{ {
gl::Buffer *buffer = activeAttrib->attribute->buffer.get(); auto *dynamicAttrib = &(*translatedAttribs)[attribIndex];
gl::Error error = storeDynamicAttrib(dynamicAttrib, start, count, instances);
if (error.isError())
{
unmapStreamingBuffer();
return error;
}
// Promote static usage of dynamic buffers.
gl::Buffer *buffer = dynamicAttrib->attribute->buffer.get();
if (buffer) if (buffer)
{ {
BufferD3D *bufferD3D = GetImplAs<BufferD3D>(buffer); BufferD3D *bufferD3D = GetImplAs<BufferD3D>(buffer);
size_t typeSize = ComputeVertexAttributeTypeSize(*activeAttrib->attribute); size_t typeSize = ComputeVertexAttributeTypeSize(*dynamicAttrib->attribute);
bufferD3D->promoteStaticUsage(count * static_cast<int>(typeSize)); bufferD3D->promoteStaticUsage(count * static_cast<int>(typeSize));
} }
} }
unmapStreamingBuffer();
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
...@@ -266,20 +411,12 @@ gl::Error VertexDataManager::reserveSpaceForAttrib(const TranslatedAttribute &tr ...@@ -266,20 +411,12 @@ gl::Error VertexDataManager::reserveSpaceForAttrib(const TranslatedAttribute &tr
GLsizei instances) const GLsizei instances) const
{ {
const gl::VertexAttribute &attrib = *translatedAttrib.attribute; const gl::VertexAttribute &attrib = *translatedAttrib.attribute;
if (DirectStoragePossible(attrib)) ASSERT(!DirectStoragePossible(attrib));
{
return gl::Error(GL_NO_ERROR);
}
gl::Buffer *buffer = attrib.buffer.get(); gl::Buffer *buffer = attrib.buffer.get();
BufferD3D *bufferD3D = buffer ? GetImplAs<BufferD3D>(buffer) : nullptr; BufferD3D *bufferD3D = buffer ? GetImplAs<BufferD3D>(buffer) : nullptr;
StaticVertexBufferInterface *staticBuffer = ASSERT(!bufferD3D || bufferD3D->getStaticVertexBuffer(attrib) == nullptr);
bufferD3D ? bufferD3D->getStaticVertexBuffer(attrib) : nullptr; UNUSED_ASSERTION_VARIABLE(bufferD3D);
if (staticBuffer)
{
return gl::Error(GL_NO_ERROR);
}
size_t totalCount = ComputeVertexAttributeElementCount(attrib, count, instances); size_t totalCount = ComputeVertexAttributeElementCount(attrib, count, instances);
ASSERT(!bufferD3D || ASSERT(!bufferD3D ||
...@@ -290,10 +427,10 @@ gl::Error VertexDataManager::reserveSpaceForAttrib(const TranslatedAttribute &tr ...@@ -290,10 +427,10 @@ gl::Error VertexDataManager::reserveSpaceForAttrib(const TranslatedAttribute &tr
instances); instances);
} }
gl::Error VertexDataManager::storeAttribute(TranslatedAttribute *translated, gl::Error VertexDataManager::storeDynamicAttrib(TranslatedAttribute *translated,
GLint start, GLint start,
GLsizei count, GLsizei count,
GLsizei instances) GLsizei instances)
{ {
const gl::VertexAttribute &attrib = *translated->attribute; const gl::VertexAttribute &attrib = *translated->attribute;
...@@ -306,16 +443,6 @@ gl::Error VertexDataManager::storeAttribute(TranslatedAttribute *translated, ...@@ -306,16 +443,6 @@ gl::Error VertexDataManager::storeAttribute(TranslatedAttribute *translated,
// Instanced vertices do not apply the 'start' offset // Instanced vertices do not apply the 'start' offset
GLint firstVertexIndex = (attrib.divisor > 0 ? 0 : start); GLint firstVertexIndex = (attrib.divisor > 0 ? 0 : start);
if (DirectStoragePossible(attrib))
{
translated->vertexBuffer.set(nullptr);
translated->storage = storage;
translated->serial = storage->getSerial();
translated->stride = static_cast<unsigned int>(ComputeVertexAttributeStride(attrib));
translated->offset = static_cast<unsigned int>(attrib.offset + translated->stride * firstVertexIndex);
return gl::Error(GL_NO_ERROR);
}
// Compute source data pointer // Compute source data pointer
const uint8_t *sourceData = nullptr; const uint8_t *sourceData = nullptr;
...@@ -344,58 +471,20 @@ gl::Error VertexDataManager::storeAttribute(TranslatedAttribute *translated, ...@@ -344,58 +471,20 @@ gl::Error VertexDataManager::storeAttribute(TranslatedAttribute *translated,
translated->storage = nullptr; translated->storage = nullptr;
translated->stride = errorOrOutputElementSize.getResult(); translated->stride = errorOrOutputElementSize.getResult();
gl::Error error(GL_NO_ERROR); size_t totalCount = ComputeVertexAttributeElementCount(attrib, count, instances);
auto *staticBuffer = storage ? storage->getStaticVertexBuffer(attrib) : nullptr;
if (staticBuffer) gl::Error error = mStreamingBuffer->storeDynamicAttribute(
attrib, translated->currentValueType, firstVertexIndex, static_cast<GLsizei>(totalCount),
instances, &streamOffset, sourceData);
if (error.isError())
{ {
if (staticBuffer->empty()) return error;
{
// Convert the entire buffer
int totalCount =
ElementsInBuffer(attrib, static_cast<unsigned int>(storage->getSize()));
int startIndex = static_cast<int>(attrib.offset) /
static_cast<int>(ComputeVertexAttributeStride(attrib));
error =
staticBuffer->storeStaticAttribute(attrib, -startIndex, totalCount, 0, sourceData);
if (error.isError())
{
return error;
}
}
unsigned int firstElementOffset =
(static_cast<unsigned int>(attrib.offset) /
static_cast<unsigned int>(ComputeVertexAttributeStride(attrib))) *
translated->stride;
ASSERT(attrib.divisor == 0 || firstVertexIndex == 0);
unsigned int startOffset = firstVertexIndex * translated->stride;
if (streamOffset + firstElementOffset + startOffset < streamOffset)
{
return gl::Error(GL_OUT_OF_MEMORY);
}
streamOffset += firstElementOffset + startOffset;
translated->vertexBuffer.set(staticBuffer->getVertexBuffer());
} }
else
{
size_t totalCount = ComputeVertexAttributeElementCount(attrib, count, instances);
error = mStreamingBuffer->storeDynamicAttribute( VertexBuffer *vertexBuffer = mStreamingBuffer->getVertexBuffer();
attrib, translated->currentValueType, firstVertexIndex,
static_cast<GLsizei>(totalCount), instances, &streamOffset, sourceData);
if (error.isError())
{
return error;
}
translated->vertexBuffer.set(mStreamingBuffer->getVertexBuffer());
}
ASSERT(translated->vertexBuffer.get()); translated->vertexBuffer.set(vertexBuffer);
translated->serial = translated->vertexBuffer.get()->getSerial(); translated->serial = vertexBuffer->getSerial();
translated->offset = streamOffset; translated->offset = streamOffset;
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
...@@ -403,9 +492,15 @@ gl::Error VertexDataManager::storeAttribute(TranslatedAttribute *translated, ...@@ -403,9 +492,15 @@ gl::Error VertexDataManager::storeAttribute(TranslatedAttribute *translated,
gl::Error VertexDataManager::storeCurrentValue(const gl::VertexAttribCurrentValueData &currentValue, gl::Error VertexDataManager::storeCurrentValue(const gl::VertexAttribCurrentValueData &currentValue,
TranslatedAttribute *translated, TranslatedAttribute *translated,
CurrentValueState *cachedState) size_t attribIndex)
{ {
auto *buffer = cachedState->buffer; CurrentValueState *cachedState = &mCurrentValueCache[attribIndex];
auto *&buffer = cachedState->buffer;
if (!buffer)
{
buffer = new StreamingVertexBufferInterface(mFactory, CONSTANT_VERTEX_BUFFER_SIZE);
}
if (cachedState->data != currentValue) if (cachedState->data != currentValue)
{ {
......
...@@ -60,6 +60,18 @@ struct TranslatedAttribute ...@@ -60,6 +60,18 @@ struct TranslatedAttribute
unsigned int divisor; unsigned int divisor;
}; };
enum class VertexStorageType
{
UNKNOWN,
STATIC, // Translate the vertex data once and re-use it.
DYNAMIC, // Translate the data every frame into a ring buffer.
DIRECT, // Bind a D3D buffer directly without any translation.
CURRENT_VALUE, // Use a single value for the attribute.
};
// Given a vertex attribute, return the type of storage it will use.
VertexStorageType ClassifyAttributeStorage(const gl::VertexAttribute &attrib);
class VertexDataManager : angle::NonCopyable class VertexDataManager : angle::NonCopyable
{ {
public: public:
...@@ -72,6 +84,23 @@ class VertexDataManager : angle::NonCopyable ...@@ -72,6 +84,23 @@ class VertexDataManager : angle::NonCopyable
std::vector<TranslatedAttribute> *translatedAttribs, std::vector<TranslatedAttribute> *translatedAttribs,
GLsizei instances); GLsizei instances);
static void StoreDirectAttrib(TranslatedAttribute *directAttrib, GLint start);
static gl::Error StoreStaticAttrib(TranslatedAttribute *translated,
GLint start,
GLsizei count,
GLsizei instances);
gl::Error storeDynamicAttribs(std::vector<TranslatedAttribute> *translatedAttribs,
const std::vector<size_t> &dynamicAttribIndexes,
GLint start,
GLsizei count,
GLsizei instances);
gl::Error storeCurrentValue(const gl::VertexAttribCurrentValueData &currentValue,
TranslatedAttribute *translated,
size_t attribIndex);
private: private:
struct CurrentValueState struct CurrentValueState
{ {
...@@ -87,14 +116,10 @@ class VertexDataManager : angle::NonCopyable ...@@ -87,14 +116,10 @@ class VertexDataManager : angle::NonCopyable
GLsizei count, GLsizei count,
GLsizei instances) const; GLsizei instances) const;
gl::Error storeAttribute(TranslatedAttribute *translated, gl::Error storeDynamicAttrib(TranslatedAttribute *translated,
GLint start, GLint start,
GLsizei count, GLsizei count,
GLsizei instances); GLsizei instances);
gl::Error storeCurrentValue(const gl::VertexAttribCurrentValueData &currentValue,
TranslatedAttribute *translated,
CurrentValueState *cachedState);
void unmapStreamingBuffer(); void unmapStreamingBuffer();
...@@ -102,12 +127,9 @@ class VertexDataManager : angle::NonCopyable ...@@ -102,12 +127,9 @@ class VertexDataManager : angle::NonCopyable
StreamingVertexBufferInterface *mStreamingBuffer; StreamingVertexBufferInterface *mStreamingBuffer;
std::vector<CurrentValueState> mCurrentValueCache; std::vector<CurrentValueState> mCurrentValueCache;
std::vector<size_t> mDynamicAttributeIndexesCache;
// Cache variables
std::vector<TranslatedAttribute *> mActiveEnabledAttributes;
std::vector<size_t> mActiveDisabledAttributes;
}; };
} } // namespace rx
#endif // LIBANGLE_RENDERER_D3D_VERTEXDATAMANAGER_H_ #endif // LIBANGLE_RENDERER_D3D_VERTEXDATAMANAGER_H_
...@@ -38,9 +38,10 @@ gl::Error Buffer9::setData(const void* data, size_t size, GLenum usage) ...@@ -38,9 +38,10 @@ gl::Error Buffer9::setData(const void* data, size_t size, GLenum usage)
memcpy(mMemory.data(), data, size); memcpy(mMemory.data(), data, size);
} }
updateD3DBufferUsage(usage);
invalidateStaticData(); invalidateStaticData();
updateD3DBufferUsage(usage);
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment