Commit 401345e4 by Jamie Madill Committed by Commit Bot

D3D11: Move more state into StateManager11.

This moves the input layout cache and vertex and index data managers and related info into the state manager. This makes it easier to manage the state application with regards to dirty bits. Also updates the dirty current value handling in StateManager11. BUG=angleproject:1156 BUG=angleproject:2052 Change-Id: I8de968a1f8416363aa1c49d9e9da129942d21275 Reviewed-on: https://chromium-review.googlesource.com/616783Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 3cb4894c
......@@ -128,15 +128,19 @@ gl::Error StreamInIndexBuffer(IndexBufferInterface *buffer,
IndexDataManager::IndexDataManager(BufferFactoryD3D *factory, RendererClass rendererClass)
: mFactory(factory),
mRendererClass(rendererClass),
mStreamingBufferShort(nullptr),
mStreamingBufferInt(nullptr)
mStreamingBufferShort(),
mStreamingBufferInt()
{
}
IndexDataManager::~IndexDataManager()
{
SafeDelete(mStreamingBufferShort);
SafeDelete(mStreamingBufferInt);
}
void IndexDataManager::deinitialize()
{
mStreamingBufferShort.reset();
mStreamingBufferInt.reset();
}
// static
......@@ -376,41 +380,19 @@ gl::Error IndexDataManager::getStreamingIndexBuffer(GLenum destinationIndexType,
IndexBufferInterface **outBuffer)
{
ASSERT(outBuffer);
if (destinationIndexType == GL_UNSIGNED_INT)
{
if (!mStreamingBufferInt)
{
mStreamingBufferInt = new StreamingIndexBufferInterface(mFactory);
gl::Error error =
mStreamingBufferInt->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT);
if (error.isError())
{
SafeDelete(mStreamingBufferInt);
return error;
}
}
*outBuffer = mStreamingBufferInt;
return gl::NoError();
}
else
{
ASSERT(destinationIndexType == GL_UNSIGNED_SHORT);
ASSERT(destinationIndexType == GL_UNSIGNED_SHORT || destinationIndexType == GL_UNSIGNED_INT);
if (!mStreamingBufferShort)
{
mStreamingBufferShort = new StreamingIndexBufferInterface(mFactory);
gl::Error error = mStreamingBufferShort->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE,
GL_UNSIGNED_SHORT);
if (error.isError())
{
SafeDelete(mStreamingBufferShort);
return error;
}
}
auto &streamingBuffer =
(destinationIndexType == GL_UNSIGNED_INT) ? mStreamingBufferInt : mStreamingBufferShort;
*outBuffer = mStreamingBufferShort;
return gl::NoError();
if (!streamingBuffer)
{
StreamingBuffer newBuffer(new StreamingIndexBufferInterface(mFactory));
ANGLE_TRY(newBuffer->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, destinationIndexType));
streamingBuffer = std::move(newBuffer);
}
*outBuffer = streamingBuffer.get();
return gl::NoError();
}
}
} // namespace rx
......@@ -68,6 +68,8 @@ class IndexDataManager : angle::NonCopyable
explicit IndexDataManager(BufferFactoryD3D *factory, RendererClass rendererClass);
virtual ~IndexDataManager();
void deinitialize();
static bool UsePrimitiveRestartWorkaround(bool primitiveRestartFixedIndexEnabled,
GLenum type,
RendererClass rendererClass);
......@@ -91,11 +93,13 @@ class IndexDataManager : angle::NonCopyable
gl::Error getStreamingIndexBuffer(GLenum destinationIndexType,
IndexBufferInterface **outBuffer);
using StreamingBuffer = std::unique_ptr<StreamingIndexBufferInterface>;
BufferFactoryD3D *const mFactory;
RendererClass mRendererClass;
StreamingIndexBufferInterface *mStreamingBufferShort;
StreamingIndexBufferInterface *mStreamingBufferInt;
std::unique_ptr<StreamingIndexBufferInterface> mStreamingBufferShort;
std::unique_ptr<StreamingIndexBufferInterface> mStreamingBufferInt;
};
}
} // namespace rx
#endif // LIBANGLE_INDEXDATAMANAGER_H_
......@@ -113,6 +113,7 @@ bool DirectStoragePossible(const gl::VertexAttribute &attrib, const gl::VertexBi
TranslatedAttribute::TranslatedAttribute()
: active(false),
attribute(nullptr),
binding(nullptr),
currentValueType(GL_NONE),
baseOffset(0),
usesFirstVertexOffset(false),
......@@ -176,9 +177,7 @@ VertexStorageType ClassifyAttributeStorage(const gl::VertexAttribute &attrib,
}
}
VertexDataManager::CurrentValueState::CurrentValueState()
: buffer(nullptr),
offset(0)
VertexDataManager::CurrentValueState::CurrentValueState() : buffer(), offset(0)
{
data.FloatValues[0] = std::numeric_limits<float>::quiet_NaN();
data.FloatValues[1] = std::numeric_limits<float>::quiet_NaN();
......@@ -189,26 +188,33 @@ VertexDataManager::CurrentValueState::CurrentValueState()
VertexDataManager::CurrentValueState::~CurrentValueState()
{
SafeDelete(buffer);
}
VertexDataManager::VertexDataManager(BufferFactoryD3D *factory)
: mFactory(factory),
mStreamingBuffer(nullptr),
// TODO(jmadill): use context caps
mCurrentValueCache(gl::MAX_VERTEX_ATTRIBS)
: mFactory(factory), mStreamingBuffer(), mCurrentValueCache(gl::MAX_VERTEX_ATTRIBS)
{
mStreamingBuffer = new StreamingVertexBufferInterface(factory, INITIAL_STREAM_BUFFER_SIZE);
}
VertexDataManager::~VertexDataManager()
{
}
gl::Error VertexDataManager::initialize()
{
mStreamingBuffer.reset(
new StreamingVertexBufferInterface(mFactory, INITIAL_STREAM_BUFFER_SIZE));
if (!mStreamingBuffer)
{
ERR() << "Failed to allocate the streaming vertex buffer.";
return gl::OutOfMemory() << "Failed to allocate the streaming vertex buffer.";
}
return gl::NoError();
}
VertexDataManager::~VertexDataManager()
void VertexDataManager::deinitialize()
{
SafeDelete(mStreamingBuffer);
mStreamingBuffer.reset();
mCurrentValueCache.clear();
}
gl::Error VertexDataManager::prepareVertexData(const gl::State &state,
......@@ -398,7 +404,7 @@ gl::Error VertexDataManager::storeDynamicAttribs(
};
// Will trigger unmapping on return.
StreamingBufferUnmapper localUnmapper(mStreamingBuffer);
StreamingBufferUnmapper localUnmapper(mStreamingBuffer.get());
// Reserve the required space for the dynamic buffers.
for (auto attribIndex : dynamicAttribsMask)
......@@ -522,11 +528,11 @@ gl::Error VertexDataManager::storeCurrentValue(const gl::VertexAttribCurrentValu
size_t attribIndex)
{
CurrentValueState *cachedState = &mCurrentValueCache[attribIndex];
auto *&buffer = cachedState->buffer;
auto &buffer = cachedState->buffer;
if (!buffer)
{
buffer = new StreamingVertexBufferInterface(mFactory, CONSTANT_VERTEX_BUFFER_SIZE);
buffer.reset(new StreamingVertexBufferInterface(mFactory, CONSTANT_VERTEX_BUFFER_SIZE));
}
if (cachedState->data != currentValue)
......
......@@ -87,6 +87,9 @@ class VertexDataManager : angle::NonCopyable
VertexDataManager(BufferFactoryD3D *factory);
virtual ~VertexDataManager();
gl::Error initialize();
void deinitialize();
gl::Error prepareVertexData(const gl::State &state,
GLint start,
GLsizei count,
......@@ -118,7 +121,7 @@ class VertexDataManager : angle::NonCopyable
CurrentValueState();
~CurrentValueState();
StreamingVertexBufferInterface *buffer;
std::unique_ptr<StreamingVertexBufferInterface> buffer;
gl::VertexAttribCurrentValueData data;
size_t offset;
};
......@@ -134,7 +137,7 @@ class VertexDataManager : angle::NonCopyable
BufferFactoryD3D *const mFactory;
StreamingVertexBufferInterface *mStreamingBuffer;
std::unique_ptr<StreamingVertexBufferInterface> mStreamingBuffer;
std::vector<CurrentValueState> mCurrentValueCache;
gl::AttributesMask mDynamicAttribsMaskCache;
};
......
......@@ -18,7 +18,6 @@
#include "libANGLE/renderer/d3d/RenderTargetD3D.h"
#include "libANGLE/renderer/d3d/RendererD3D.h"
#include "libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h"
#include "libANGLE/renderer/d3d/d3d11/InputLayoutCache.h"
#include "libANGLE/renderer/d3d/d3d11/RenderStateCache.h"
#include "libANGLE/renderer/d3d/d3d11/ResourceManager11.h"
#include "libANGLE/renderer/d3d/d3d11/StateManager11.h"
......@@ -146,18 +145,6 @@ class Renderer11 : public RendererD3D
gl::Error applyUniforms(const ProgramD3D &programD3D,
GLenum drawMode,
const std::vector<D3DUniform *> &uniformArray) override;
gl::Error applyVertexBuffer(const gl::Context *context,
GLenum mode,
GLint first,
GLsizei count,
GLsizei instances,
TranslatedIndexData *indexInfo);
gl::Error applyIndexBuffer(const gl::ContextState &data,
const void *indices,
GLsizei count,
GLenum mode,
GLenum type,
TranslatedIndexData *indexInfo);
gl::Error applyTransformFeedbackBuffers(const gl::ContextState &data);
// lost device
......@@ -384,7 +371,6 @@ class Renderer11 : public RendererD3D
const Renderer11DeviceCaps &getRenderer11DeviceCaps() const { return mRenderer11DeviceCaps; };
RendererClass getRendererClass() const override { return RENDERER_D3D11; }
InputLayoutCache *getInputLayoutCache() { return &mInputLayoutCache; }
StateManager11 *getStateManager() { return &mStateManager; }
void onSwap();
......@@ -542,7 +528,7 @@ class Renderer11 : public RendererD3D
const gl::TextureCaps &depthStencilBufferFormatCaps) const;
egl::Error initializeD3DDevice();
void initializeDevice();
egl::Error initializeDevice();
void releaseDeviceResources();
void release();
......@@ -563,12 +549,6 @@ class Renderer11 : public RendererD3D
StateManager11 mStateManager;
// Currently applied index buffer
ID3D11Buffer *mAppliedIB;
DXGI_FORMAT mAppliedIBFormat;
unsigned int mAppliedIBOffset;
bool mAppliedIBChanged;
// Currently applied transform feedback buffers
uintptr_t mAppliedTFObject;
......@@ -592,11 +572,6 @@ class Renderer11 : public RendererD3D
uintptr_t mCurrentGeometryConstantBuffer;
// Vertex, index and input layouts
VertexDataManager *mVertexDataManager;
IndexDataManager *mIndexDataManager;
InputLayoutCache mInputLayoutCache;
StreamingIndexBufferInterface *mLineLoopIB;
StreamingIndexBufferInterface *mTriangleFanIB;
......
......@@ -14,7 +14,9 @@
#include "libANGLE/Query.h"
#include "libANGLE/VertexArray.h"
#include "libANGLE/renderer/d3d/TextureD3D.h"
#include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
#include "libANGLE/renderer/d3d/d3d11/Framebuffer11.h"
#include "libANGLE/renderer/d3d/d3d11/IndexBuffer11.h"
#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
#include "libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h"
......@@ -287,7 +289,13 @@ StateManager11::StateManager11(Renderer11 *renderer)
mCurrentInputLayout(),
mInputLayoutIsDirty(false),
mDirtyVertexBufferRange(gl::MAX_VERTEX_ATTRIBS, 0),
mCurrentPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_UNDEFINED)
mCurrentPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_UNDEFINED),
mAppliedIB(nullptr),
mAppliedIBFormat(DXGI_FORMAT_UNKNOWN),
mAppliedIBOffset(0),
mAppliedIBChanged(false),
mVertexDataManager(renderer),
mIndexDataManager(renderer, RENDERER_D3D11)
{
mCurBlendState.blend = false;
mCurBlendState.sourceBlendRGB = GL_ONE;
......@@ -996,6 +1004,10 @@ void StateManager11::invalidateEverything(const gl::Context *context)
std::fill(mForceSetVertexSamplerStates.begin(), mForceSetVertexSamplerStates.end(), true);
std::fill(mForceSetPixelSamplerStates.begin(), mForceSetPixelSamplerStates.end(), true);
std::fill(mForceSetComputeSamplerStates.begin(), mForceSetComputeSamplerStates.end(), true);
mAppliedIB = nullptr;
mAppliedIBFormat = DXGI_FORMAT_UNKNOWN;
mAppliedIBOffset = 0;
}
void StateManager11::invalidateVertexBuffer()
......@@ -1155,7 +1167,7 @@ void StateManager11::unsetConflictingAttachmentResources(
}
}
void StateManager11::initialize(const gl::Caps &caps)
gl::Error StateManager11::initialize(const gl::Caps &caps)
{
mCurVertexSRVs.initialize(caps.maxVertexTextureImageUnits);
mCurPixelSRVs.initialize(caps.maxTextureImageUnits);
......@@ -1176,11 +1188,17 @@ void StateManager11::initialize(const gl::Caps &caps)
mSamplerMetadataVS.initData(caps.maxVertexTextureImageUnits);
mSamplerMetadataPS.initData(caps.maxTextureImageUnits);
mSamplerMetadataCS.initData(caps.maxComputeTextureImageUnits);
ANGLE_TRY(mVertexDataManager.initialize());
return gl::NoError();
}
void StateManager11::deinitialize()
{
mCurrentValueAttribs.clear();
mInputLayoutCache.clear();
mVertexDataManager.deinitialize();
mIndexDataManager.deinitialize();
}
gl::Error StateManager11::syncFramebuffer(const gl::Context *context, gl::Framebuffer *framebuffer)
......@@ -1266,21 +1284,31 @@ gl::Error StateManager11::syncFramebuffer(const gl::Context *context, gl::Frameb
return gl::NoError();
}
gl::Error StateManager11::updateCurrentValueAttribs(const gl::State &state,
VertexDataManager *vertexDataManager)
void StateManager11::invalidateCurrentValueAttrib(size_t attribIndex)
{
mDirtyCurrentValueAttribs.set(attribIndex);
}
gl::Error StateManager11::syncCurrentValueAttribs(const gl::State &state)
{
const auto &activeAttribsMask = state.getProgram()->getActiveAttribLocationsMask();
const auto &dirtyActiveAttribs = (activeAttribsMask & mDirtyCurrentValueAttribs);
const auto &vertexAttributes = state.getVertexArray()->getVertexAttributes();
const auto &vertexBindings = state.getVertexArray()->getVertexBindings();
if (!dirtyActiveAttribs.any())
{
return gl::NoError();
}
invalidateVertexBuffer();
mDirtyCurrentValueAttribs = (mDirtyCurrentValueAttribs & ~dirtyActiveAttribs);
for (auto attribIndex : dirtyActiveAttribs)
{
if (vertexAttributes[attribIndex].enabled)
continue;
mDirtyCurrentValueAttribs.reset(attribIndex);
const auto *attrib = &vertexAttributes[attribIndex];
const auto &currentValue = state.getVertexAttribCurrentValue(attribIndex);
auto currentValueAttrib = &mCurrentValueAttribs[attribIndex];
......@@ -1288,18 +1316,13 @@ gl::Error StateManager11::updateCurrentValueAttribs(const gl::State &state,
currentValueAttrib->attribute = attrib;
currentValueAttrib->binding = &vertexBindings[attrib->bindingIndex];
ANGLE_TRY(vertexDataManager->storeCurrentValue(currentValue, currentValueAttrib,
ANGLE_TRY(mVertexDataManager.storeCurrentValue(currentValue, currentValueAttrib,
static_cast<size_t>(attribIndex)));
}
return gl::NoError();
}
const std::vector<TranslatedAttribute> &StateManager11::getCurrentValueAttribs() const
{
return mCurrentValueAttribs;
}
void StateManager11::setInputLayout(const d3d11::InputLayout *inputLayout)
{
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
......@@ -1784,4 +1807,108 @@ gl::Error StateManager11::syncProgram(const gl::Context *context, GLenum drawMod
return gl::NoError();
}
gl::Error StateManager11::applyVertexBuffer(const gl::Context *context,
GLenum mode,
GLint first,
GLsizei count,
GLsizei instances,
TranslatedIndexData *indexInfo)
{
const auto &state = context->getGLState();
const auto &vertexArray = state.getVertexArray();
auto *vertexArray11 = GetImplAs<VertexArray11>(vertexArray);
ANGLE_TRY(vertexArray11->updateDirtyAndDynamicAttribs(context, &mVertexDataManager, first,
count, instances));
ANGLE_TRY(syncCurrentValueAttribs(state));
// If index information is passed, mark it with the current changed status.
if (indexInfo)
{
indexInfo->srcIndexData.srcIndicesChanged = mAppliedIBChanged;
}
GLsizei numIndicesPerInstance = 0;
if (instances > 0)
{
numIndicesPerInstance = count;
}
const auto &vertexArrayAttribs = vertexArray11->getTranslatedAttribs();
ANGLE_TRY(mInputLayoutCache.applyVertexBuffers(mRenderer, state, vertexArrayAttribs,
mCurrentValueAttribs, mode, first, indexInfo,
numIndicesPerInstance));
// InputLayoutCache::applyVertexBuffers calls through to the Bufer11 to get the native vertex
// buffer (ID3D11Buffer *). Because we allocate these buffers lazily, this will trigger
// allocation. This in turn will signal that the buffer is dirty. Since we just resolved the
// dirty-ness in VertexArray11::updateDirtyAndDynamicAttribs, this can make us do a needless
// update on the second draw call.
// Hence we clear the flags here, after we've applied vertex data, since we know everything
// is clean. This is a bit of a hack.
vertexArray11->clearDirtyAndPromoteDynamicAttribs(state, count);
return gl::NoError();
}
gl::Error StateManager11::applyIndexBuffer(const gl::ContextState &data,
const void *indices,
GLsizei count,
GLenum type,
TranslatedIndexData *indexInfo)
{
const auto &glState = data.getState();
gl::VertexArray *vao = glState.getVertexArray();
gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get();
ANGLE_TRY(mIndexDataManager.prepareIndexData(type, count, elementArrayBuffer, indices,
indexInfo, glState.isPrimitiveRestartEnabled()));
ID3D11Buffer *buffer = nullptr;
DXGI_FORMAT bufferFormat =
(indexInfo->indexType == GL_UNSIGNED_INT) ? DXGI_FORMAT_R32_UINT : DXGI_FORMAT_R16_UINT;
if (indexInfo->storage)
{
Buffer11 *storage = GetAs<Buffer11>(indexInfo->storage);
ANGLE_TRY_RESULT(storage->getBuffer(BUFFER_USAGE_INDEX), buffer);
}
else
{
IndexBuffer11 *indexBuffer = GetAs<IndexBuffer11>(indexInfo->indexBuffer);
buffer = indexBuffer->getBuffer().get();
}
mAppliedIBChanged = false;
setIndexBuffer(buffer, bufferFormat, indexInfo->startOffset, true);
return gl::NoError();
}
void StateManager11::setIndexBuffer(ID3D11Buffer *buffer,
DXGI_FORMAT indexFormat,
unsigned int offset,
bool indicesChanged)
{
if (buffer != mAppliedIB || indexFormat != mAppliedIBFormat || offset != mAppliedIBOffset)
{
mRenderer->getDeviceContext()->IASetIndexBuffer(buffer, indexFormat, offset);
mAppliedIB = buffer;
mAppliedIBFormat = indexFormat;
mAppliedIBOffset = offset;
if (indicesChanged)
{
mAppliedIBChanged = true;
}
}
}
gl::Error StateManager11::updateVertexOffsetsForPointSpritesEmulation(GLint startVertex,
GLsizei emulatedInstanceId)
{
return mInputLayoutCache.updateVertexOffsetsForPointSpritesEmulation(mRenderer, startVertex,
emulatedInstanceId);
}
} // namespace rx
......@@ -11,13 +11,15 @@
#include <array>
#include "libANGLE/angletypes.h"
#include "libANGLE/ContextState.h"
#include "libANGLE/State.h"
#include "libANGLE/angletypes.h"
#include "libANGLE/renderer/d3d/IndexDataManager.h"
#include "libANGLE/renderer/d3d/RendererD3D.h"
#include "libANGLE/renderer/d3d/d3d11/InputLayoutCache.h"
#include "libANGLE/renderer/d3d/d3d11/Query11.h"
#include "libANGLE/renderer/d3d/d3d11/RenderStateCache.h"
#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
#include "libANGLE/renderer/d3d/d3d11/Query11.h"
#include "libANGLE/renderer/d3d/RendererD3D.h"
namespace rx
{
......@@ -82,7 +84,7 @@ class StateManager11 final : angle::NonCopyable
StateManager11(Renderer11 *renderer);
~StateManager11();
void initialize(const gl::Caps &caps);
gl::Error initialize(const gl::Caps &caps);
void deinitialize();
void syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits);
......@@ -114,6 +116,9 @@ class StateManager11 final : angle::NonCopyable
void invalidateVertexBuffer();
void invalidateEverything(const gl::Context *context);
// Called from VertexArray11::updateVertexAttribStorage.
void invalidateCurrentValueAttrib(size_t attribIndex);
void setOneTimeRenderTarget(const gl::Context *context,
ID3D11RenderTargetView *rtv,
ID3D11DepthStencilView *dsv);
......@@ -126,11 +131,6 @@ class StateManager11 final : angle::NonCopyable
void onDeleteQueryObject(Query11 *query);
gl::Error onMakeCurrent(const gl::Context *context);
gl::Error updateCurrentValueAttribs(const gl::State &state,
VertexDataManager *vertexDataManager);
const std::vector<TranslatedAttribute> &getCurrentValueAttribs() const;
void setInputLayout(const d3d11::InputLayout *inputLayout);
// TODO(jmadill): Migrate to d3d11::Buffer.
......@@ -155,6 +155,31 @@ class StateManager11 final : angle::NonCopyable
void setPixelShader(const d3d11::PixelShader *shader);
void setComputeShader(const d3d11::ComputeShader *shader);
// Not handled by an internal dirty bit because of the extra draw parameters.
gl::Error applyVertexBuffer(const gl::Context *context,
GLenum mode,
GLint first,
GLsizei count,
GLsizei instances,
TranslatedIndexData *indexInfo);
gl::Error applyIndexBuffer(const gl::ContextState &data,
const void *indices,
GLsizei count,
GLenum type,
TranslatedIndexData *indexInfo);
void setIndexBuffer(ID3D11Buffer *buffer,
DXGI_FORMAT indexFormat,
unsigned int offset,
bool indicesChanged);
gl::Error updateVertexOffsetsForPointSpritesEmulation(GLint startVertex,
GLsizei emulatedInstanceId);
// Only used in testing.
InputLayoutCache *getInputLayoutCache() { return &mInputLayoutCache; }
private:
void unsetConflictingSRVs(gl::SamplerType shaderType,
uintptr_t resource,
......@@ -200,6 +225,8 @@ class StateManager11 final : angle::NonCopyable
// Faster than calling setTexture a jillion times
gl::Error clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd);
gl::Error syncCurrentValueAttribs(const gl::State &state);
enum DirtyBitType
{
DIRTY_BIT_RENDER_TARGET,
......@@ -334,6 +361,17 @@ class StateManager11 final : angle::NonCopyable
SamplerMetadata11 mSamplerMetadataVS;
SamplerMetadata11 mSamplerMetadataPS;
SamplerMetadata11 mSamplerMetadataCS;
// Currently applied index buffer
ID3D11Buffer *mAppliedIB;
DXGI_FORMAT mAppliedIBFormat;
unsigned int mAppliedIBOffset;
bool mAppliedIBChanged;
// Vertex, index and input layouts
VertexDataManager mVertexDataManager;
IndexDataManager mIndexDataManager;
InputLayoutCache mInputLayoutCache;
};
} // namespace rx
......
......@@ -121,13 +121,20 @@ void VertexArray11::updateVertexAttribStorage(const gl::Context *context, size_t
Buffer11 *oldBuffer11 = oldBufferGL ? GetImplAs<Buffer11>(oldBufferGL) : nullptr;
Buffer11 *newBuffer11 = newBufferGL ? GetImplAs<Buffer11>(newBufferGL) : nullptr;
StateManager11 *stateManager = GetImplAs<Context11>(context)->getRenderer()->getStateManager();
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.
OnBufferDataDirtyChannel *newChannel = nullptr;
if (newBuffer11 != nullptr)
if (newStorageType == VertexStorageType::CURRENT_VALUE)
{
stateManager->invalidateCurrentValueAttrib(attribIndex);
}
else if (newBuffer11 != nullptr)
{
// Note that for static callbacks, promotion to a static buffer from a dynamic buffer
// means we need to tag dynamic buffers with static callbacks.
switch (newStorageType)
{
case VertexStorageType::DIRECT:
......@@ -138,9 +145,11 @@ void VertexArray11::updateVertexAttribStorage(const gl::Context *context, size_t
newChannel = newBuffer11->getStaticBroadcastChannel();
break;
default:
UNREACHABLE();
break;
}
}
mOnBufferDataDirty[attribIndex].bind(newChannel);
mCurrentBuffers[attribIndex].set(context, binding.getBuffer().get());
}
......
......@@ -339,7 +339,7 @@ egl::Error Renderer9::initialize()
mAdapter, mDeviceType, currentDisplayMode.Format,
D3DUSAGE_QUERY_VERTEXTEXTURE, D3DRTYPE_TEXTURE, D3DFMT_R16F));
initializeDevice();
ANGLE_TRY(initializeDevice());
return egl::NoError();
}
......@@ -347,7 +347,7 @@ egl::Error Renderer9::initialize()
// do any one-time device initialization
// NOTE: this is also needed after a device lost/reset
// to reset the scene status and ensure the default states are reset.
void Renderer9::initializeDevice()
egl::Error Renderer9::initializeDevice()
{
// Permanent non-default states
mDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);
......@@ -382,9 +382,16 @@ void Renderer9::initializeDevice()
mVertexDataManager = new VertexDataManager(this);
mIndexDataManager = new IndexDataManager(this, getRendererClass());
if (mVertexDataManager->initialize().isError())
{
return egl::EglBadAlloc() << "Error initializing VertexDataManager";
}
mTranslatedAttribCache.resize(getNativeCaps().maxVertexAttributes);
mStateManager.initialize();
return egl::NoError();
}
D3DPRESENT_PARAMETERS Renderer9::getDefaultPresentParameters()
......@@ -2362,7 +2369,10 @@ bool Renderer9::resetDevice()
if (!removedDevice)
{
// reset device defaults
initializeDevice();
if (initializeDevice().isError())
{
return false;
}
}
return true;
......
......@@ -456,7 +456,7 @@ class Renderer9 : public RendererD3D
HMODULE mD3d9Module;
void initializeDevice();
egl::Error initializeDevice();
D3DPRESENT_PARAMETERS getDefaultPresentParameters();
void releaseDeviceResources();
......
......@@ -68,7 +68,7 @@ TEST_P(D3D11InputLayoutCacheTest, StressTest)
gl::Context *context = reinterpret_cast<gl::Context *>(getEGLWindow()->getContext());
rx::Context11 *context11 = rx::GetImplAs<rx::Context11>(context);
rx::Renderer11 *renderer11 = context11->getRenderer();
rx::InputLayoutCache *inputLayoutCache = renderer11->getInputLayoutCache();
rx::InputLayoutCache *inputLayoutCache = renderer11->getStateManager()->getInputLayoutCache();
// Clamp the cache size to something tiny
inputLayoutCache->setCacheSize(4);
......
......@@ -860,6 +860,60 @@ TEST_P(VertexAttributeTest, DrawArraysWithDisabledAttribute)
EXPECT_GL_NO_ERROR();
}
// Test based on WebGL Test attribs/gl-disabled-vertex-attrib.html
TEST_P(VertexAttributeTest, DisabledAttribArrays)
{
// Known failure on Retina MBP: http://crbug.com/635081
ANGLE_SKIP_TEST_IF(IsOSX() && IsNVIDIA());
const std::string vsSource =
"attribute vec4 a_position;\n"
"attribute vec4 a_color;\n"
"varying vec4 v_color;\n"
"bool isCorrectColor(vec4 v) {\n"
" return v.x == 0.0 && v.y == 0.0 && v.z == 0.0 && v.w == 1.0;\n"
"}"
"void main() {\n"
" gl_Position = a_position;\n"
" v_color = isCorrectColor(a_color) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);\n"
"}";
const std::string fsSource =
"varying mediump vec4 v_color;\n"
"void main() {\n"
" gl_FragColor = v_color;\n"
"}";
GLint maxVertexAttribs = 0;
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs);
for (GLint colorIndex = 0; colorIndex < maxVertexAttribs; ++colorIndex)
{
GLuint vs = CompileShader(GL_VERTEX_SHADER, vsSource);
ASSERT_NE(0u, vs);
GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource);
ASSERT_NE(0u, fs);
GLuint program = glCreateProgram();
glBindAttribLocation(program, colorIndex, "a_color");
glAttachShader(program, vs);
glDeleteShader(vs);
glAttachShader(program, fs);
glDeleteShader(fs);
ASSERT_TRUE(LinkAttachedProgram(program));
drawQuad(program, "a_position", 0.5f);
ASSERT_GL_NO_ERROR();
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
glDeleteProgram(program);
}
}
class VertexAttributeTestES31 : public VertexAttributeTestES3
{
protected:
......
......@@ -208,3 +208,9 @@ GLuint LoadBinaryProgramES3(const std::vector<uint8_t> &binary, GLenum binaryFor
glProgramBinary(program, binaryFormat, binary.data(), static_cast<GLint>(binary.size()));
return CheckLinkStatusAndReturnProgram(program, true);
}
bool LinkAttachedProgram(GLuint program)
{
glLinkProgram(program);
return (CheckLinkStatusAndReturnProgram(program, true) != 0);
}
......@@ -32,6 +32,7 @@ ANGLE_EXPORT GLuint CompileProgram(const std::string &vsSource, const std::strin
ANGLE_EXPORT GLuint CompileProgramFromFiles(const std::string &vsPath, const std::string &fsPath);
ANGLE_EXPORT GLuint CompileComputeProgram(const std::string &csSource,
bool outputErrorMessages = true);
ANGLE_EXPORT bool LinkAttachedProgram(GLuint program);
ANGLE_EXPORT GLuint LoadBinaryProgramOES(const std::vector<uint8_t> &binary, GLenum binaryFormat);
ANGLE_EXPORT GLuint LoadBinaryProgramES3(const std::vector<uint8_t> &binary, GLenum binaryFormat);
......
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