Commit 00f394ec by Corentin Wallez

Revert Dirty bits for VertexArray11

This is a combination of two reverts: Revert "D3D11: Remove unused mRenderer from VertexArray11." Revert "D3D11: Implement dirty bits for VertexArray11." Reverting only the first commit would trigger warnings on the Windows clang bot. BUG=594509 BUG=angleproject:1327 This reverts commit fc4712b5. This reverts commit 7d8585b8. Change-Id: I612dbba0816d6144f71ce815701c13a798585bc7 Reviewed-on: https://chromium-review.googlesource.com/332989Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent a0fc18d9
......@@ -29,7 +29,9 @@ VertexArray::Data::~Data()
}
VertexArray::VertexArray(rx::ImplFactory *factory, GLuint id, size_t maxAttribs)
: mId(id), mData(maxAttribs), mVertexArray(factory->createVertexArray(mData))
: mId(id),
mVertexArray(factory->createVertexArray(mData)),
mData(maxAttribs)
{
}
......
......@@ -114,10 +114,10 @@ class VertexArray final : public LabeledObject
private:
GLuint mId;
rx::VertexArrayImpl *mVertexArray;
Data mData;
DirtyBits mDirtyBits;
rx::VertexArrayImpl *mVertexArray;
};
}
......
......@@ -161,13 +161,13 @@ void BufferD3D::invalidateStaticData()
// Creates static buffers if sufficient used data has been left unmodified
void BufferD3D::promoteStaticUsage(int dataSize)
{
if (mUsage == D3DBufferUsage::DYNAMIC)
if (mStaticVertexBuffers.empty() && !mStaticIndexBuffer)
{
mUnmodifiedDataUse += dataSize;
if (mUnmodifiedDataUse > 3 * getSize())
{
updateD3DBufferUsage(GL_STATIC_DRAW);
initializeStaticData();
}
}
}
......
......@@ -43,8 +43,8 @@ class BufferD3D : public BufferImpl
StaticVertexBufferInterface *getStaticVertexBuffer(const gl::VertexAttribute &attribute);
StaticIndexBufferInterface *getStaticIndexBuffer();
virtual void initializeStaticData();
virtual void invalidateStaticData();
void initializeStaticData();
void invalidateStaticData();
void promoteStaticUsage(int dataSize);
......
......@@ -55,6 +55,7 @@ RendererD3D::~RendererD3D()
void RendererD3D::cleanup()
{
mTranslatedAttribCache.clear();
mScratchMemoryBuffer.resize(0);
for (auto &incompleteTexture : mIncompleteTextures)
{
......
......@@ -282,6 +282,8 @@ class RendererD3D : public Renderer, public BufferFactoryD3D
void initializeDebugAnnotator();
gl::DebugAnnotator *mAnnotator;
std::vector<TranslatedAttribute> mTranslatedAttribCache;
bool mPresentPathFastEnabled;
private:
......
......@@ -80,7 +80,7 @@ class VertexBufferInterface : angle::NonCopyable
unsigned int getSerial() const;
VertexBuffer *getVertexBuffer() const;
VertexBuffer* getVertexBuffer() const;
protected:
gl::Error discard();
......
......@@ -9,7 +9,6 @@
#include "libANGLE/renderer/d3d/VertexDataManager.h"
#include "common/BitSetIterator.h"
#include "libANGLE/Buffer.h"
#include "libANGLE/formatutils.h"
#include "libANGLE/Program.h"
......@@ -202,7 +201,7 @@ gl::Error VertexDataManager::prepareVertexData(const gl::State &state,
const gl::VertexArray *vertexArray = state.getVertexArray();
const auto &vertexAttributes = vertexArray->getVertexAttributes();
mDynamicAttribsMaskCache.reset();
mDynamicAttributeIndexesCache.clear();
const gl::Program *program = state.getProgram();
translatedAttribs->clear();
......@@ -242,7 +241,7 @@ gl::Error VertexDataManager::prepareVertexData(const gl::State &state,
}
case VertexStorageType::DYNAMIC:
// Dynamic attributes must be handled together.
mDynamicAttribsMaskCache.set(attribIndex);
mDynamicAttributeIndexesCache.push_back(attribIndex);
break;
case VertexStorageType::DIRECT:
// Update translated data for direct attributes.
......@@ -263,12 +262,12 @@ gl::Error VertexDataManager::prepareVertexData(const gl::State &state,
}
}
if (mDynamicAttribsMaskCache.none())
if (mDynamicAttributeIndexesCache.empty())
{
gl::Error(GL_NO_ERROR);
}
return storeDynamicAttribs(translatedAttribs, mDynamicAttribsMaskCache, start, count,
return storeDynamicAttribs(translatedAttribs, mDynamicAttributeIndexesCache, start, count,
instances);
}
......@@ -366,13 +365,13 @@ gl::Error VertexDataManager::StoreStaticAttrib(TranslatedAttribute *translated,
gl::Error VertexDataManager::storeDynamicAttribs(
std::vector<TranslatedAttribute> *translatedAttribs,
const gl::AttributesMask &dynamicAttribsMask,
const std::vector<size_t> &dynamicAttribIndexes,
GLint start,
GLsizei count,
GLsizei instances)
{
// Reserve the required space for the dynamic buffers.
for (auto attribIndex : angle::IterateBitSet(dynamicAttribsMask))
for (size_t attribIndex : dynamicAttribIndexes)
{
const auto &dynamicAttrib = (*translatedAttribs)[attribIndex];
gl::Error error = reserveSpaceForAttrib(dynamicAttrib, count, instances);
......@@ -383,7 +382,7 @@ gl::Error VertexDataManager::storeDynamicAttribs(
}
// Store dynamic attributes
for (auto attribIndex : angle::IterateBitSet(dynamicAttribsMask))
for (size_t attribIndex : dynamicAttribIndexes)
{
auto *dynamicAttrib = &(*translatedAttribs)[attribIndex];
gl::Error error = storeDynamicAttrib(dynamicAttrib, start, count, instances);
......@@ -392,14 +391,8 @@ gl::Error VertexDataManager::storeDynamicAttribs(
unmapStreamingBuffer();
return error;
}
}
unmapStreamingBuffer();
// Promote static usage of dynamic buffers.
for (auto attribIndex : angle::IterateBitSet(dynamicAttribsMask))
{
auto *dynamicAttrib = &(*translatedAttribs)[attribIndex];
// Promote static usage of dynamic buffers.
gl::Buffer *buffer = dynamicAttrib->attribute->buffer.get();
if (buffer)
{
......@@ -409,6 +402,7 @@ gl::Error VertexDataManager::storeDynamicAttribs(
}
}
unmapStreamingBuffer();
return gl::Error(GL_NO_ERROR);
}
......
......@@ -10,10 +10,9 @@
#ifndef LIBANGLE_RENDERER_D3D_VERTEXDATAMANAGER_H_
#define LIBANGLE_RENDERER_D3D_VERTEXDATAMANAGER_H_
#include "common/angleutils.h"
#include "libANGLE/angletypes.h"
#include "libANGLE/Constants.h"
#include "libANGLE/VertexAttribute.h"
#include "common/angleutils.h"
namespace gl
{
......@@ -93,7 +92,7 @@ class VertexDataManager : angle::NonCopyable
GLsizei instances);
gl::Error storeDynamicAttribs(std::vector<TranslatedAttribute> *translatedAttribs,
const gl::AttributesMask &dynamicAttribsMask,
const std::vector<size_t> &dynamicAttribIndexes,
GLint start,
GLsizei count,
GLsizei instances);
......@@ -128,7 +127,7 @@ class VertexDataManager : angle::NonCopyable
StreamingVertexBufferInterface *mStreamingBuffer;
std::vector<CurrentValueState> mCurrentValueCache;
gl::AttributesMask mDynamicAttribsMaskCache;
std::vector<size_t> mDynamicAttributeIndexesCache;
};
} // namespace rx
......
......@@ -127,7 +127,7 @@ class Buffer11::BufferStorage : angle::NonCopyable
class Buffer11::NativeStorage : public Buffer11::BufferStorage
{
public:
NativeStorage(Renderer11 *renderer, BufferUsage usage, const NotificationSet *onStorageChanged);
NativeStorage(Renderer11 *renderer, BufferUsage usage);
~NativeStorage() override;
bool isMappable() const override { return mUsage == BUFFER_USAGE_STAGING; }
......@@ -149,7 +149,6 @@ class Buffer11::NativeStorage : public Buffer11::BufferStorage
unsigned int bufferSize);
ID3D11Buffer *mNativeStorage;
const NotificationSet *mOnStorageChanged;
};
// A emulated indexed buffer storage represents an underlying D3D11 buffer for data
......@@ -665,7 +664,23 @@ Buffer11::BufferStorage *Buffer11::getBufferStorage(BufferUsage usage)
if (!newStorage)
{
newStorage = allocateStorage(usage);
if (usage == BUFFER_USAGE_PIXEL_PACK)
{
newStorage = new PackStorage(mRenderer);
}
else if (usage == BUFFER_USAGE_SYSTEM_MEMORY)
{
newStorage = new SystemMemoryStorage(mRenderer);
}
else if (usage == BUFFER_USAGE_EMULATED_INDEXED_VERTEX)
{
newStorage = new EmulatedIndexedStorage(mRenderer);
}
else
{
// buffer is not allocated, create it
newStorage = new NativeStorage(mRenderer, usage);
}
}
// resize buffer
......@@ -683,23 +698,6 @@ Buffer11::BufferStorage *Buffer11::getBufferStorage(BufferUsage usage)
return newStorage;
}
Buffer11::BufferStorage *Buffer11::allocateStorage(BufferUsage usage) const
{
switch (usage)
{
case BUFFER_USAGE_PIXEL_PACK:
return new PackStorage(mRenderer);
case BUFFER_USAGE_SYSTEM_MEMORY:
return new SystemMemoryStorage(mRenderer);
case BUFFER_USAGE_EMULATED_INDEXED_VERTEX:
return new EmulatedIndexedStorage(mRenderer);
case BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK:
return new NativeStorage(mRenderer, usage, &mDirectBufferDirtyCallbacks);
default:
return new NativeStorage(mRenderer, usage, nullptr);
}
}
Buffer11::BufferStorage *Buffer11::getConstantBufferRangeStorage(GLintptr offset, GLsizeiptr size)
{
BufferStorage *newStorage;
......@@ -711,7 +709,7 @@ Buffer11::BufferStorage *Buffer11::getConstantBufferRangeStorage(GLintptr offset
if (!cacheEntry->storage)
{
cacheEntry->storage = allocateStorage(BUFFER_USAGE_UNIFORM);
cacheEntry->storage = new NativeStorage(mRenderer, BUFFER_USAGE_UNIFORM);
cacheEntry->lruCount = ++mMaxConstantBufferLruCount;
}
......@@ -850,43 +848,8 @@ bool Buffer11::supportsDirectBinding() const
{
// Do not support direct buffers for dynamic data. The streaming buffer
// offers better performance for data which changes every frame.
return (mUsage == D3DBufferUsage::STATIC);
}
void Buffer11::initializeStaticData()
{
BufferD3D::initializeStaticData();
// Notify when static data changes.
mStaticBufferDirtyCallbacks.signal();
}
void Buffer11::invalidateStaticData()
{
BufferD3D::invalidateStaticData();
// Notify when static data changes.
mStaticBufferDirtyCallbacks.signal();
}
void Buffer11::addStaticBufferDirtyCallback(const NotificationCallback *callback)
{
mStaticBufferDirtyCallbacks.add(callback);
}
void Buffer11::removeStaticBufferDirtyCallback(const NotificationCallback *callback)
{
mStaticBufferDirtyCallbacks.remove(callback);
}
void Buffer11::addDirectBufferDirtyCallback(const NotificationCallback *callback)
{
mDirectBufferDirtyCallbacks.add(callback);
}
void Buffer11::removeDirectBufferDirtyCallback(const NotificationCallback *callback)
{
mDirectBufferDirtyCallbacks.remove(callback);
// Check for absence of static buffer interfaces to detect dynamic data.
return (!mStaticVertexBuffers.empty() && mStaticIndexBuffer);
}
Buffer11::BufferStorage::BufferStorage(Renderer11 *renderer, BufferUsage usage)
......@@ -911,10 +874,8 @@ gl::Error Buffer11::BufferStorage::setData(const uint8_t *data, size_t offset, s
return gl::Error(GL_NO_ERROR);
}
Buffer11::NativeStorage::NativeStorage(Renderer11 *renderer,
BufferUsage usage,
const NotificationSet *onStorageChanged)
: BufferStorage(renderer, usage), mNativeStorage(nullptr), mOnStorageChanged(onStorageChanged)
Buffer11::NativeStorage::NativeStorage(Renderer11 *renderer, BufferUsage usage)
: BufferStorage(renderer, usage), mNativeStorage(nullptr)
{
}
......@@ -1026,12 +987,6 @@ gl::Error Buffer11::NativeStorage::resize(size_t size, bool preserveData)
mBufferSize = bufferDesc.ByteWidth;
// Notify that the storage has changed.
if (mOnStorageChanged)
{
mOnStorageChanged->signal();
}
return gl::Error(GL_NO_ERROR);
}
......@@ -1471,4 +1426,4 @@ void Buffer11::SystemMemoryStorage::unmap()
{
// No-op
}
} // namespace rx
}
......@@ -13,7 +13,6 @@
#include "libANGLE/angletypes.h"
#include "libANGLE/renderer/d3d/BufferD3D.h"
#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
namespace gl
{
......@@ -67,38 +66,24 @@ class Buffer11 : public BufferD3D
ID3D11Buffer *getEmulatedIndexedBuffer(SourceIndexData *indexInfo, const TranslatedAttribute *attribute);
ID3D11Buffer *getConstantBufferRange(GLintptr offset, GLsizeiptr size);
ID3D11ShaderResourceView *getSRV(DXGI_FORMAT srvFormat);
bool isMapped() const { return mMappedStorage != nullptr; }
bool isMapped() const { return mMappedStorage != NULL; }
gl::Error packPixels(const gl::FramebufferAttachment &readAttachment,
const PackPixelsParams &params);
size_t getTotalCPUBufferMemoryBytes() const;
// BufferD3D implementation
size_t getSize() const override { return mSize; }
bool supportsDirectBinding() const override;
virtual size_t getSize() const { return mSize; }
virtual bool supportsDirectBinding() const;
gl::Error getData(const uint8_t **outData) override;
void initializeStaticData() override;
void invalidateStaticData() override;
// BufferImpl implementation
gl::Error setData(const void *data, size_t size, GLenum usage) override;
gl::Error setSubData(const void *data, size_t size, size_t offset) override;
gl::Error copySubData(BufferImpl *source,
GLintptr sourceOffset,
GLintptr destOffset,
GLsizeiptr size) override;
gl::Error map(GLenum access, GLvoid **mapPtr) override;
gl::Error mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) override;
gl::Error unmap(GLboolean *result) override;
void markTransformFeedbackUsage() override;
// We use two set of dirty callbacks for two events. Static buffers are marked dirty whenever
// the data is changed, because they must be re-translated. Direct buffers only need to be
// updated when the underlying ID3D11Buffer pointer changes - hopefully far less often.
void addStaticBufferDirtyCallback(const NotificationCallback *callback);
void removeStaticBufferDirtyCallback(const NotificationCallback *callback);
void addDirectBufferDirtyCallback(const NotificationCallback *callback);
void removeDirectBufferDirtyCallback(const NotificationCallback *callback);
virtual gl::Error setData(const void* data, size_t size, GLenum usage);
virtual gl::Error setSubData(const void* data, size_t size, size_t offset);
virtual gl::Error copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size);
virtual gl::Error map(GLenum access, GLvoid **mapPtr);
virtual gl::Error mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr);
virtual gl::Error unmap(GLboolean *result);
virtual void markTransformFeedbackUsage();
private:
class BufferStorage;
......@@ -107,6 +92,13 @@ class Buffer11 : public BufferD3D
class PackStorage;
class SystemMemoryStorage;
Renderer11 *mRenderer;
size_t mSize;
BufferStorage *mMappedStorage;
std::vector<BufferStorage*> mBufferStorages;
struct ConstantBufferCacheEntry
{
ConstantBufferCacheEntry() : storage(nullptr), lruCount(0) { }
......@@ -115,26 +107,6 @@ class Buffer11 : public BufferD3D
unsigned int lruCount;
};
void markBufferUsage();
NativeStorage *getStagingStorage();
PackStorage *getPackStorage();
gl::Error getSystemMemoryStorage(SystemMemoryStorage **storageOut);
void updateBufferStorage(BufferStorage *storage, size_t sourceOffset, size_t storageSize);
BufferStorage *getBufferStorage(BufferUsage usage);
BufferStorage *getLatestBufferStorage() const;
BufferStorage *getConstantBufferRangeStorage(GLintptr offset, GLsizeiptr size);
BufferStorage *allocateStorage(BufferUsage usage) const;
Renderer11 *mRenderer;
size_t mSize;
BufferStorage *mMappedStorage;
std::vector<BufferStorage *> mBufferStorages;
// Cache of D3D11 constant buffer for specific ranges of buffer data.
// This is used to emulate UBO ranges on 11.0 devices.
// Constant buffers are indexed by there start offset.
......@@ -148,10 +120,20 @@ class Buffer11 : public BufferD3D
unsigned int mReadUsageCount;
NotificationSet mStaticBufferDirtyCallbacks;
NotificationSet mDirectBufferDirtyCallbacks;
void markBufferUsage();
NativeStorage *getStagingStorage();
PackStorage *getPackStorage();
gl::Error getSystemMemoryStorage(SystemMemoryStorage **storageOut);
void updateBufferStorage(BufferStorage *storage, size_t sourceOffset, size_t storageSize);
BufferStorage *getBufferStorage(BufferUsage usage);
BufferStorage *getLatestBufferStorage() const;
BufferStorage *getConstantBufferRangeStorage(GLintptr offset, GLsizeiptr size);
void invalidateEmulatedIndexedBuffer();
};
} // namespace rx
}
#endif // LIBANGLE_RENDERER_D3D_D3D11_BUFFER11_H_
......@@ -94,8 +94,7 @@ Optional<size_t> FindFirstNonInstanced(
}
void SortAttributesByLayout(const gl::Program *program,
const std::vector<TranslatedAttribute> &vertexArrayAttribs,
const std::vector<TranslatedAttribute> &currentValueAttribs,
const std::vector<TranslatedAttribute> &unsortedAttributes,
AttribIndexArray *sortedD3DSemanticsOut,
std::vector<const TranslatedAttribute *> *sortedAttributesOut)
{
......@@ -113,17 +112,7 @@ void SortAttributesByLayout(const gl::Program *program,
}
(*sortedD3DSemanticsOut)[d3dSemantic] = d3dSemantic;
const auto *arrayAttrib = &vertexArrayAttribs[locationIndex];
if (arrayAttrib->attribute && arrayAttrib->attribute->enabled)
{
(*sortedAttributesOut)[d3dSemantic] = arrayAttrib;
}
else
{
ASSERT(currentValueAttribs[locationIndex].attribute);
(*sortedAttributesOut)[d3dSemantic] = &currentValueAttribs[locationIndex];
}
(*sortedAttributesOut)[d3dSemantic] = &unsortedAttributes[locationIndex];
}
}
......@@ -220,8 +209,7 @@ void InputLayoutCache::markDirty()
gl::Error InputLayoutCache::applyVertexBuffers(
const gl::State &state,
const std::vector<TranslatedAttribute> &vertexArrayAttribs,
const std::vector<TranslatedAttribute> &currentValueAttribs,
const std::vector<TranslatedAttribute> &unsortedAttributes,
GLenum mode,
TranslatedIndexData *indexInfo,
GLsizei numIndicesPerInstance)
......@@ -235,7 +223,7 @@ gl::Error InputLayoutCache::applyVertexBuffers(
bool instancedPointSpritesActive = programUsesInstancedPointSprites && (mode == GL_POINTS);
AttribIndexArray sortedSemanticIndices;
SortAttributesByLayout(program, vertexArrayAttribs, currentValueAttribs, &sortedSemanticIndices,
SortAttributesByLayout(program, unsortedAttributes, &sortedSemanticIndices,
&mCurrentAttributes);
// If we are using FL 9_3, make sure the first attribute is not instanced
......
......@@ -46,8 +46,7 @@ class InputLayoutCache : angle::NonCopyable
void markDirty();
gl::Error applyVertexBuffers(const gl::State &state,
const std::vector<TranslatedAttribute> &vertexArrayAttribs,
const std::vector<TranslatedAttribute> &currentValueAttribs,
const std::vector<TranslatedAttribute> &attributes,
GLenum mode,
TranslatedIndexData *indexInfo,
GLsizei numIndicesPerInstance);
......
......@@ -189,17 +189,23 @@ RenderTarget11::~RenderTarget11()
void RenderTarget11::addDirtyCallback(const NotificationCallback *callback)
{
mDirtyCallbacks.add(callback);
mDirtyCallbacks.insert(callback);
}
void RenderTarget11::removeDirtyCallback(const NotificationCallback *callback)
{
mDirtyCallbacks.remove(callback);
mDirtyCallbacks.erase(callback);
}
void RenderTarget11::signalDirty()
{
mDirtyCallbacks.signal();
if (mDirtyCallbacks.empty())
return;
for (const auto &callback : mDirtyCallbacks)
{
(*callback)();
}
// Clear the signal list. We can't do this in the callback because it mutates the iterator.
mDirtyCallbacks.clear();
......
......@@ -41,7 +41,8 @@ class RenderTarget11 : public RenderTargetD3D
d3d11::ANGLEFormat getANGLEFormat() const { return mANGLEFormat; }
protected:
NotificationSet mDirtyCallbacks;
std::set<const NotificationCallback *> mDirtyCallbacks;
d3d11::ANGLEFormat mANGLEFormat;
};
......
......@@ -833,6 +833,9 @@ void Renderer11::initializeDevice()
ANGLE_HISTOGRAM_ENUMERATION("GPU.ANGLE.D3D11FeatureLevel",
angleFeatureLevel,
NUM_ANGLE_FEATURE_LEVELS);
// TODO(jmadill): use context caps, and place in common D3D location
mTranslatedAttribCache.resize(getRendererCaps().maxVertexAttributes);
}
void Renderer11::populateRenderer11DeviceCaps()
......@@ -1495,17 +1498,7 @@ gl::Error Renderer11::applyVertexBuffer(const gl::State &state,
GLsizei instances,
TranslatedIndexData *indexInfo)
{
const auto &vertexArray = state.getVertexArray();
auto *vertexArray11 = GetImplAs<VertexArray11>(vertexArray);
gl::Error error = vertexArray11->updateDirtyAndDynamicAttribs(mVertexDataManager, state, first,
count, instances);
if (error.isError())
{
return error;
}
error = mStateManager.updateCurrentValueAttribs(state, mVertexDataManager);
gl::Error error = mVertexDataManager->prepareVertexData(state, first, count, &mTranslatedAttribCache, instances);
if (error.isError())
{
return error;
......@@ -1522,10 +1515,8 @@ gl::Error Renderer11::applyVertexBuffer(const gl::State &state,
{
numIndicesPerInstance = count;
}
const auto &vertexArrayAttribs = vertexArray11->getTranslatedAttribs();
const auto &currentValueAttribs = mStateManager.getCurrentValueAttribs();
return mInputLayoutCache.applyVertexBuffers(state, vertexArrayAttribs, currentValueAttribs,
mode, indexInfo, numIndicesPerInstance);
return mInputLayoutCache.applyVertexBuffers(state, mTranslatedAttribCache, mode, indexInfo,
numIndicesPerInstance);
}
gl::Error Renderer11::applyIndexBuffer(const gl::Data &data,
......@@ -2471,7 +2462,6 @@ void Renderer11::markAllStateDirty()
void Renderer11::releaseDeviceResources()
{
mStateManager.deinitialize();
mStateCache.clear();
mInputLayoutCache.clear();
......@@ -4302,5 +4292,4 @@ egl::Error Renderer11::getEGLDevice(DeviceImpl **device)
*device = static_cast<DeviceImpl *>(mEGLDevice);
return egl::Error(EGL_SUCCESS);
}
} // namespace rx
}
......@@ -150,9 +150,7 @@ StateManager11::StateManager11(Renderer11 *renderer)
mCurNear(0.0f),
mCurFar(0.0f),
mViewportBounds(),
mRenderTargetIsDirty(false),
mDirtyCurrentValueAttribs(),
mCurrentValueAttribs()
mRenderTargetIsDirty(false)
{
mCurBlendState.blend = false;
mCurBlendState.sourceBlendRGB = GL_ONE;
......@@ -193,9 +191,6 @@ StateManager11::StateManager11(Renderer11 *renderer)
mCurRasterState.polygonOffsetUnits = 0.0f;
mCurRasterState.pointDrawMode = false;
mCurRasterState.multiSample = false;
// Initially all current value attributes must be updated on first use.
mDirtyCurrentValueAttribs.flip();
}
StateManager11::~StateManager11()
......@@ -246,7 +241,7 @@ void StateManager11::syncState(const gl::State &state, const gl::State::DirtyBit
return;
}
for (auto dirtyBit : angle::IterateBitSet(dirtyBits))
for (unsigned int dirtyBit : angle::IterateBitSet(dirtyBits))
{
switch (dirtyBit)
{
......@@ -466,13 +461,6 @@ void StateManager11::syncState(const gl::State &state, const gl::State::DirtyBit
mRenderTargetIsDirty = true;
break;
default:
if (dirtyBit >= gl::State::DIRTY_BIT_CURRENT_VALUE_0 &&
dirtyBit < gl::State::DIRTY_BIT_CURRENT_VALUE_MAX)
{
size_t attribIndex =
static_cast<size_t>(dirtyBit - gl::State::DIRTY_BIT_CURRENT_VALUE_0);
mDirtyCurrentValueAttribs.set(attribIndex);
}
break;
}
}
......@@ -970,13 +958,6 @@ void StateManager11::initialize(const gl::Caps &caps)
// Initialize cached NULL SRV block
mNullSRVs.resize(caps.maxTextureImageUnits, nullptr);
mCurrentValueAttribs.resize(caps.maxVertexAttributes);
}
void StateManager11::deinitialize()
{
mCurrentValueAttribs.clear();
}
gl::Error StateManager11::syncFramebuffer(const gl::Framebuffer *framebuffer)
......@@ -1097,40 +1078,4 @@ gl::Error StateManager11::syncFramebuffer(const gl::Framebuffer *framebuffer)
return gl::Error(GL_NO_ERROR);
}
gl::Error StateManager11::updateCurrentValueAttribs(const gl::State &state,
VertexDataManager *vertexDataManager)
{
const auto &activeAttribsMask = state.getProgram()->getActiveAttribLocationsMask();
const auto &dirtyActiveAttribs = (activeAttribsMask & mDirtyCurrentValueAttribs);
const auto &vertexAttributes = state.getVertexArray()->getVertexAttributes();
for (auto attribIndex : angle::IterateBitSet(dirtyActiveAttribs))
{
if (vertexAttributes[attribIndex].enabled)
continue;
mDirtyCurrentValueAttribs.reset(attribIndex);
const auto &currentValue =
state.getVertexAttribCurrentValue(static_cast<unsigned int>(attribIndex));
auto currentValueAttrib = &mCurrentValueAttribs[attribIndex];
currentValueAttrib->currentValueType = currentValue.Type;
currentValueAttrib->attribute = &vertexAttributes[attribIndex];
gl::Error error = vertexDataManager->storeCurrentValue(currentValue, currentValueAttrib,
static_cast<size_t>(attribIndex));
if (error.isError())
{
return error;
}
}
return gl::Error(GL_NO_ERROR);
}
const std::vector<TranslatedAttribute> &StateManager11::getCurrentValueAttribs() const
{
return mCurrentValueAttribs;
}
} // namespace rx
......@@ -48,7 +48,6 @@ class StateManager11 final : angle::NonCopyable
~StateManager11();
void initialize(const gl::Caps &caps);
void deinitialize();
void syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits);
gl::Error setBlendState(const gl::Framebuffer *framebuffer,
......@@ -92,11 +91,6 @@ class StateManager11 final : angle::NonCopyable
void onDeleteQueryObject(Query11 *query);
gl::Error onMakeCurrent(const gl::Data &data);
gl::Error updateCurrentValueAttribs(const gl::State &state,
VertexDataManager *vertexDataManager);
const std::vector<TranslatedAttribute> &getCurrentValueAttribs() const;
private:
void setViewportBounds(const int width, const int height);
void unsetConflictingSRVs(gl::SamplerType shaderType,
......@@ -192,10 +186,6 @@ class StateManager11 final : angle::NonCopyable
// A block of NULL pointers, cached so we don't re-allocate every draw call
std::vector<ID3D11ShaderResourceView *> mNullSRVs;
// Current translations of "Current-Value" data - owned by Context, not VertexArray.
gl::AttributesMask mDirtyCurrentValueAttribs;
std::vector<TranslatedAttribute> mCurrentValueAttribs;
};
} // namespace rx
......
//
// Copyright 2016 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// VertexArray11:
// Implementation of rx::VertexArray11.
//
#include "libANGLE/renderer/d3d/d3d11/VertexArray11.h"
#include "common/BitSetIterator.h"
#include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
namespace rx
{
namespace
{
size_t GetAttribIndex(unsigned long dirtyBit)
{
if (dirtyBit >= gl::VertexArray::DIRTY_BIT_ATTRIB_0_ENABLED &&
dirtyBit < gl::VertexArray::DIRTY_BIT_ATTRIB_MAX_ENABLED)
{
return dirtyBit - gl::VertexArray::DIRTY_BIT_ATTRIB_0_ENABLED;
}
if (dirtyBit >= gl::VertexArray::DIRTY_BIT_ATTRIB_0_POINTER &&
dirtyBit < gl::VertexArray::DIRTY_BIT_ATTRIB_MAX_POINTER)
{
return dirtyBit - gl::VertexArray::DIRTY_BIT_ATTRIB_0_POINTER;
}
ASSERT(dirtyBit >= gl::VertexArray::DIRTY_BIT_ATTRIB_0_DIVISOR &&
dirtyBit < gl::VertexArray::DIRTY_BIT_ATTRIB_MAX_DIVISOR);
return static_cast<size_t>(dirtyBit) - gl::VertexArray::DIRTY_BIT_ATTRIB_0_DIVISOR;
}
} // anonymous namespace
VertexArray11::VertexArray11(const gl::VertexArray::Data &data)
: VertexArrayImpl(data),
mAttributeStorageTypes(data.getVertexAttributes().size(), VertexStorageType::CURRENT_VALUE),
mTranslatedAttribs(data.getVertexAttributes().size()),
mCurrentBuffers(data.getVertexAttributes().size())
{
for (size_t attribIndex = 0; attribIndex < mCurrentBuffers.size(); ++attribIndex)
{
auto callback = [this, attribIndex]()
{
this->markBufferDataDirty(attribIndex);
};
mOnBufferDataDirty.push_back(callback);
}
}
VertexArray11::~VertexArray11()
{
for (auto &binding : mCurrentBuffers)
{
binding.set(nullptr);
}
}
void VertexArray11::syncState(const gl::VertexArray::DirtyBits &dirtyBits)
{
for (auto dirtyBit : angle::IterateBitSet(dirtyBits))
{
if (dirtyBit == gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER)
continue;
size_t attribIndex = GetAttribIndex(dirtyBit);
mAttribsToUpdate.set(attribIndex);
}
}
void VertexArray11::updateVertexAttribStorage(size_t attribIndex)
{
const auto &attrib = mData.getVertexAttribute(attribIndex);
// Note: having an unchanged storage type doesn't mean the attribute is clean.
auto oldStorageType = mAttributeStorageTypes[attribIndex];
auto newStorageType = ClassifyAttributeStorage(attrib);
mAttributeStorageTypes[attribIndex] = newStorageType;
if (newStorageType == VertexStorageType::DYNAMIC)
{
if (oldStorageType != VertexStorageType::DYNAMIC)
{
// Sync dynamic attribs in a different set.
mAttribsToTranslate.reset(attribIndex);
mDynamicAttribsMask.set(attribIndex);
}
}
else
{
mAttribsToTranslate.set(attribIndex);
if (oldStorageType == VertexStorageType::DYNAMIC)
{
ASSERT(mDynamicAttribsMask[attribIndex]);
mDynamicAttribsMask.reset(attribIndex);
}
}
gl::Buffer *oldBufferGL = mCurrentBuffers[attribIndex].get();
gl::Buffer *newBufferGL = attrib.buffer.get();
Buffer11 *oldBuffer11 = oldBufferGL ? GetImplAs<Buffer11>(oldBufferGL) : nullptr;
Buffer11 *newBuffer11 = newBufferGL ? GetImplAs<Buffer11>(newBufferGL) : nullptr;
if (oldBuffer11 != newBuffer11 || oldStorageType != newStorageType)
{
// Note that for static callbacks, promotion to a static buffer from a dynamic buffer means
// we need to tag dynamic buffers with static callbacks.
if (oldBuffer11 != nullptr)
{
if (oldStorageType == VertexStorageType::DIRECT)
{
oldBuffer11->removeDirectBufferDirtyCallback(&mOnBufferDataDirty[attribIndex]);
}
else if (oldStorageType == VertexStorageType::STATIC ||
oldStorageType == VertexStorageType::DYNAMIC)
{
oldBuffer11->removeStaticBufferDirtyCallback(&mOnBufferDataDirty[attribIndex]);
}
}
if (newBuffer11 != nullptr)
{
if (newStorageType == VertexStorageType::DIRECT)
{
newBuffer11->addDirectBufferDirtyCallback(&mOnBufferDataDirty[attribIndex]);
}
else if (newStorageType == VertexStorageType::STATIC ||
newStorageType == VertexStorageType::DYNAMIC)
{
newBuffer11->addStaticBufferDirtyCallback(&mOnBufferDataDirty[attribIndex]);
}
}
mCurrentBuffers[attribIndex] = attrib.buffer;
}
}
gl::Error VertexArray11::updateDirtyAndDynamicAttribs(VertexDataManager *vertexDataManager,
const gl::State &state,
GLint start,
GLsizei count,
GLsizei instances)
{
const gl::Program *program = state.getProgram();
const auto &activeLocations = program->getActiveAttribLocationsMask();
if (mAttribsToUpdate.any())
{
// Skip attrib locations the program doesn't use.
const auto &activeToUpdate = (mAttribsToUpdate & activeLocations);
for (auto toUpdateIndex : angle::IterateBitSet(activeToUpdate))
{
mAttribsToUpdate.reset(toUpdateIndex);
updateVertexAttribStorage(toUpdateIndex);
}
}
const auto &attribs = mData.getVertexAttributes();
if (mAttribsToTranslate.any())
{
// Skip attrib locations the program doesn't use, saving for the next frame.
const auto &dirtyActiveAttribs = (mAttribsToTranslate & activeLocations);
for (auto dirtyAttribIndex : angle::IterateBitSet(dirtyActiveAttribs))
{
mAttribsToTranslate.reset(dirtyAttribIndex);
auto *translatedAttrib = &mTranslatedAttribs[dirtyAttribIndex];
const auto &currentValue =
state.getVertexAttribCurrentValue(static_cast<unsigned int>(dirtyAttribIndex));
// Record basic attrib info
translatedAttrib->attribute = &attribs[dirtyAttribIndex];
translatedAttrib->currentValueType = currentValue.Type;
translatedAttrib->divisor = translatedAttrib->attribute->divisor;
switch (mAttributeStorageTypes[dirtyAttribIndex])
{
case VertexStorageType::DIRECT:
VertexDataManager::StoreDirectAttrib(translatedAttrib, start);
break;
case VertexStorageType::STATIC:
{
auto error = VertexDataManager::StoreStaticAttrib(translatedAttrib, start,
count, instances);
if (error.isError())
{
return error;
}
break;
}
case VertexStorageType::CURRENT_VALUE:
// Current value attribs are managed by the StateManager11.
break;
default:
UNREACHABLE();
break;
}
}
}
if (mDynamicAttribsMask.any())
{
auto activeDynamicAttribs = (mDynamicAttribsMask & activeLocations);
for (auto dynamicAttribIndex : angle::IterateBitSet(activeDynamicAttribs))
{
auto *dynamicAttrib = &mTranslatedAttribs[dynamicAttribIndex];
const auto &currentValue =
state.getVertexAttribCurrentValue(static_cast<unsigned int>(dynamicAttribIndex));
// Record basic attrib info
dynamicAttrib->attribute = &attribs[dynamicAttribIndex];
dynamicAttrib->currentValueType = currentValue.Type;
dynamicAttrib->divisor = dynamicAttrib->attribute->divisor;
}
return vertexDataManager->storeDynamicAttribs(&mTranslatedAttribs, activeDynamicAttribs,
start, count, instances);
}
return gl::Error(GL_NO_ERROR);
}
const std::vector<TranslatedAttribute> &VertexArray11::getTranslatedAttribs() const
{
return mTranslatedAttribs;
}
void VertexArray11::markBufferDataDirty(size_t attribIndex)
{
ASSERT(mAttributeStorageTypes[attribIndex] != VertexStorageType::CURRENT_VALUE);
// This can change a buffer's storage, we'll need to re-check.
mAttribsToUpdate.set(attribIndex);
}
} // namespace rx
......@@ -19,40 +19,13 @@ class Renderer11;
class VertexArray11 : public VertexArrayImpl
{
public:
VertexArray11(const gl::VertexArray::Data &data);
~VertexArray11() override;
void syncState(const gl::VertexArray::DirtyBits &dirtyBits) override;
gl::Error updateDirtyAndDynamicAttribs(VertexDataManager *vertexDataManager,
const gl::State &state,
GLint start,
GLsizei count,
GLsizei instances);
const std::vector<TranslatedAttribute> &getTranslatedAttribs() const;
private:
void updateVertexAttribStorage(size_t attribIndex);
void markBufferDataDirty(size_t attribIndex);
std::vector<VertexStorageType> mAttributeStorageTypes;
std::vector<TranslatedAttribute> mTranslatedAttribs;
// The mask of attributes marked as dynamic.
gl::AttributesMask mDynamicAttribsMask;
// A mask of attributes that need to be re-evaluated.
gl::AttributesMask mAttribsToUpdate;
// A set of attributes we know are dirty, and need to be re-translated.
gl::AttributesMask mAttribsToTranslate;
// We need to keep a safe pointer to the Buffer so we can attach the correct dirty callbacks.
std::vector<BindingPointer<gl::Buffer>> mCurrentBuffers;
std::vector<NotificationCallback> mOnBufferDataDirty;
VertexArray11(const gl::VertexArray::Data &data)
: VertexArrayImpl(data)
{
}
virtual ~VertexArray11() {}
};
} // namespace rx
}
#endif // LIBANGLE_RENDERER_D3D_D3D11_VERTEXARRAY11_H_
......@@ -1716,40 +1716,4 @@ bool UsePresentPathFast(const Renderer11 *renderer,
renderer->presentPathFastEnabled());
}
NotificationSet::NotificationSet()
{
}
NotificationSet::~NotificationSet()
{
}
void NotificationSet::add(const NotificationCallback *callback)
{
ASSERT(mCallbacks.count(callback) == 0);
mCallbacks.insert(callback);
}
void NotificationSet::remove(const NotificationCallback *callback)
{
ASSERT(mCallbacks.count(callback) == 1);
mCallbacks.erase(callback);
}
void NotificationSet::signal() const
{
if (mCallbacks.empty())
return;
for (const auto *callback : mCallbacks)
{
(*callback)();
}
}
void NotificationSet::clear()
{
mCallbacks.clear();
}
} // namespace rx
......@@ -406,21 +406,6 @@ bool UsePresentPathFast(const Renderer11 *renderer, const gl::FramebufferAttachm
using NotificationCallback = std::function<void()>;
class NotificationSet final : angle::NonCopyable
{
public:
NotificationSet();
~NotificationSet();
void add(const NotificationCallback *callback);
void remove(const NotificationCallback *callback);
void signal() const;
void clear();
private:
std::set<const NotificationCallback *> mCallbacks;
};
} // namespace rx
#endif // LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_UTILS_H_
......@@ -154,8 +154,6 @@ void Renderer9::release()
{
RendererD3D::cleanup();
mTranslatedAttribCache.clear();
releaseDeviceResources();
SafeDelete(mEGLDevice);
......@@ -366,6 +364,7 @@ void Renderer9::initializeDevice()
mVertexDataManager = new VertexDataManager(this);
mIndexDataManager = new IndexDataManager(this, getRendererClass());
// TODO(jmadill): use context caps, and place in common D3D location
mTranslatedAttribCache.resize(getRendererCaps().maxVertexAttributes);
}
......
......@@ -393,7 +393,6 @@ class Renderer9 : public RendererD3D
UINT mMaxNullColorbufferLRU;
DeviceD3D *mEGLDevice;
std::vector<TranslatedAttribute> mTranslatedAttribCache;
};
}
......
......@@ -387,7 +387,6 @@
'libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp',
'libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.h',
'libANGLE/renderer/d3d/d3d11/texture_format_table.h',
'libANGLE/renderer/d3d/d3d11/VertexArray11.cpp',
'libANGLE/renderer/d3d/d3d11/VertexArray11.h',
'libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp',
'libANGLE/renderer/d3d/d3d11/VertexBuffer11.h',
......
......@@ -207,31 +207,6 @@ TEST_P(BufferDataTest, DISABLED_HugeSetDataShouldNotCrash)
delete[] data;
}
// Internally in D3D, we promote dynamic data to static after many draw loops. This code tests
// path.
TEST_P(BufferDataTest, RepeatedDrawWithDynamic)
{
std::vector<GLfloat> data;
for (int i = 0; i < 16; ++i)
{
data.push_back(static_cast<GLfloat>(i));
}
glUseProgram(mProgram);
glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * data.size(), data.data(), GL_DYNAMIC_DRAW);
glVertexAttribPointer(mAttribLocation, 1, GL_FLOAT, GL_FALSE, 0, nullptr);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glEnableVertexAttribArray(mAttribLocation);
for (int drawCount = 0; drawCount < 40; ++drawCount)
{
drawQuad(mProgram, "position", 0.5f);
}
EXPECT_GL_NO_ERROR();
}
class IndexedBufferCopyTest : public ANGLETest
{
protected:
......
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