Commit 8047c0d2 by Jamie Madill Committed by Commit Bot

D3D11: Clean up InputLayoutCache.

This change does a couple things. First, it uses the 'active attribs' mask in the gl::Program to sort the translated attributes, instead of checking the translated attribute themselves. This means we don't have to consult the 'active' field of the translated attributes, which in turns means we don't have to update the active field in the attributes, which breaks the dependency of the attributes on the gl::Program. Second, use a dynamically sized array for storing the cached vertex attributes in the InputLayoutCache. This is nice because it means we don't have to store the size of the array separately. Also some other refactoring cleanups. Refactoring change only. BUG=angleproject:1327 Change-Id: Iab22de92840b30674b92eca72e450673ed9f6d6d Reviewed-on: https://chromium-review.googlesource.com/330172Reviewed-by: 's avatarZhenyao Mo <zmo@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent e9e15349
...@@ -79,28 +79,6 @@ bool IsRowMajorLayout(const sh::ShaderVariable &var) ...@@ -79,28 +79,6 @@ bool IsRowMajorLayout(const sh::ShaderVariable &var)
return false; return false;
} }
struct AttributeSorter
{
AttributeSorter(const ProgramD3D::SemanticIndexArray &semanticIndices)
: originalIndices(&semanticIndices)
{
}
bool operator()(int a, int b)
{
int indexA = (*originalIndices)[a];
int indexB = (*originalIndices)[b];
if (indexA == -1)
return false;
if (indexB == -1)
return true;
return (indexA < indexB);
}
const ProgramD3D::SemanticIndexArray *originalIndices;
};
// true if varying x has a higher priority in packing than y // true if varying x has a higher priority in packing than y
bool ComparePackedVarying(const PackedVarying &x, const PackedVarying &y) bool ComparePackedVarying(const PackedVarying &x, const PackedVarying &y)
{ {
...@@ -772,10 +750,9 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) ...@@ -772,10 +750,9 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
return LinkResult(false, gl::Error(GL_NO_ERROR)); return LinkResult(false, gl::Error(GL_NO_ERROR));
} }
// TODO(jmadill): replace MAX_VERTEX_ATTRIBS for (int &index : mAttribLocationToD3DSemantic)
for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; ++i)
{ {
stream->readInt(&mSemanticIndexes[i]); stream->readInt(&index);
} }
const unsigned int psSamplerCount = stream->readInt<unsigned int>(); const unsigned int psSamplerCount = stream->readInt<unsigned int>();
...@@ -983,7 +960,6 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) ...@@ -983,7 +960,6 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
} }
initializeUniformStorage(); initializeUniformStorage();
initAttributesByLayout();
return LinkResult(true, gl::Error(GL_NO_ERROR)); return LinkResult(true, gl::Error(GL_NO_ERROR));
} }
...@@ -999,10 +975,9 @@ gl::Error ProgramD3D::save(gl::BinaryOutputStream *stream) ...@@ -999,10 +975,9 @@ gl::Error ProgramD3D::save(gl::BinaryOutputStream *stream)
stream->writeInt(ANGLE_COMPILE_OPTIMIZATION_LEVEL); stream->writeInt(ANGLE_COMPILE_OPTIMIZATION_LEVEL);
// TODO(jmadill): replace MAX_VERTEX_ATTRIBS for (int d3dSemantic : mAttribLocationToD3DSemantic)
for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; ++i)
{ {
stream->writeInt(mSemanticIndexes[i]); stream->writeInt(d3dSemantic);
} }
stream->writeInt(mSamplersPS.size()); stream->writeInt(mSamplersPS.size());
...@@ -1465,7 +1440,7 @@ LinkResult ProgramD3D::link(const gl::Data &data, gl::InfoLog &infoLog) ...@@ -1465,7 +1440,7 @@ LinkResult ProgramD3D::link(const gl::Data &data, gl::InfoLog &infoLog)
mGeometryShaderPreamble = mDynamicHLSL->generateGeometryShaderPreamble(varyingPacking); mGeometryShaderPreamble = mDynamicHLSL->generateGeometryShaderPreamble(varyingPacking);
} }
initSemanticIndex(); initAttribLocationsToD3DSemantic();
defineUniformsAndAssignRegisters(); defineUniformsAndAssignRegisters();
...@@ -2173,8 +2148,7 @@ void ProgramD3D::reset() ...@@ -2173,8 +2148,7 @@ void ProgramD3D::reset()
mUsedPixelSamplerRange = 0; mUsedPixelSamplerRange = 0;
mDirtySamplerMapping = true; mDirtySamplerMapping = true;
std::fill(mSemanticIndexes, mSemanticIndexes + ArraySize(mSemanticIndexes), -1); mAttribLocationToD3DSemantic.fill(-1);
std::fill(mAttributesByLayout, mAttributesByLayout + ArraySize(mAttributesByLayout), -1);
mStreamOutVaryings.clear(); mStreamOutVaryings.clear();
...@@ -2191,7 +2165,7 @@ unsigned int ProgramD3D::issueSerial() ...@@ -2191,7 +2165,7 @@ unsigned int ProgramD3D::issueSerial()
return mCurrentSerial++; return mCurrentSerial++;
} }
void ProgramD3D::initSemanticIndex() void ProgramD3D::initAttribLocationsToD3DSemantic()
{ {
const gl::Shader *vertexShader = mData.getAttachedVertexShader(); const gl::Shader *vertexShader = mData.getAttachedVertexShader();
ASSERT(vertexShader != nullptr); ASSERT(vertexShader != nullptr);
...@@ -2199,41 +2173,14 @@ void ProgramD3D::initSemanticIndex() ...@@ -2199,41 +2173,14 @@ void ProgramD3D::initSemanticIndex()
// Init semantic index // Init semantic index
for (const sh::Attribute &attribute : mData.getAttributes()) for (const sh::Attribute &attribute : mData.getAttributes())
{ {
int attributeIndex = attribute.location; int d3dSemantic = vertexShader->getSemanticIndex(attribute.name);
int index = vertexShader->getSemanticIndex(attribute.name); int regCount = gl::VariableRegisterCount(attribute.type);
int regs = gl::VariableRegisterCount(attribute.type);
for (int reg = 0; reg < regs; ++reg) for (int reg = 0; reg < regCount; ++reg)
{ {
mSemanticIndexes[attributeIndex + reg] = index + reg; mAttribLocationToD3DSemantic[attribute.location + reg] = d3dSemantic + reg;
} }
} }
initAttributesByLayout();
}
void ProgramD3D::initAttributesByLayout()
{
for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
{
mAttributesByLayout[i] = i;
}
std::sort(&mAttributesByLayout[0], &mAttributesByLayout[gl::MAX_VERTEX_ATTRIBS],
AttributeSorter(mSemanticIndexes));
}
void ProgramD3D::sortAttributesByLayout(
const std::vector<TranslatedAttribute> &unsortedAttributes,
int sortedSemanticIndicesOut[gl::MAX_VERTEX_ATTRIBS],
const rx::TranslatedAttribute *sortedAttributesOut[gl::MAX_VERTEX_ATTRIBS]) const
{
for (size_t attribIndex = 0; attribIndex < unsortedAttributes.size(); ++attribIndex)
{
int oldIndex = mAttributesByLayout[attribIndex];
sortedSemanticIndicesOut[attribIndex] = mSemanticIndexes[oldIndex];
sortedAttributesOut[attribIndex] = &unsortedAttributes[oldIndex];
}
} }
void ProgramD3D::updateCachedInputLayout(const gl::State &state) void ProgramD3D::updateCachedInputLayout(const gl::State &state)
...@@ -2241,19 +2188,19 @@ void ProgramD3D::updateCachedInputLayout(const gl::State &state) ...@@ -2241,19 +2188,19 @@ void ProgramD3D::updateCachedInputLayout(const gl::State &state)
mCachedInputLayout.clear(); mCachedInputLayout.clear();
const auto &vertexAttributes = state.getVertexArray()->getVertexAttributes(); const auto &vertexAttributes = state.getVertexArray()->getVertexAttributes();
for (unsigned int attributeIndex : angle::IterateBitSet(mData.getActiveAttribLocationsMask())) for (unsigned int locationIndex : angle::IterateBitSet(mData.getActiveAttribLocationsMask()))
{ {
int semanticIndex = mSemanticIndexes[attributeIndex]; int d3dSemantic = mAttribLocationToD3DSemantic[locationIndex];
if (semanticIndex != -1) if (d3dSemantic != -1)
{ {
if (mCachedInputLayout.size() < static_cast<size_t>(semanticIndex + 1)) if (mCachedInputLayout.size() < static_cast<size_t>(d3dSemantic + 1))
{ {
mCachedInputLayout.resize(semanticIndex + 1, gl::VERTEX_FORMAT_INVALID); mCachedInputLayout.resize(d3dSemantic + 1, gl::VERTEX_FORMAT_INVALID);
} }
mCachedInputLayout[semanticIndex] = mCachedInputLayout[d3dSemantic] =
GetVertexFormatType(vertexAttributes[attributeIndex], GetVertexFormatType(vertexAttributes[locationIndex],
state.getVertexAttribCurrentValue(attributeIndex).Type); state.getVertexAttribCurrentValue(locationIndex).Type);
} }
} }
} }
...@@ -2357,4 +2304,4 @@ bool ProgramD3D::getUniformBlockMemberInfo(const std::string &memberUniformName, ...@@ -2357,4 +2304,4 @@ bool ProgramD3D::getUniformBlockMemberInfo(const std::string &memberUniformName,
*memberInfoOut = infoIter->second; *memberInfoOut = infoIter->second;
return true; return true;
} }
} } // namespace rx
...@@ -134,8 +134,6 @@ class ProgramD3DMetadata : angle::NonCopyable ...@@ -134,8 +134,6 @@ class ProgramD3DMetadata : angle::NonCopyable
class ProgramD3D : public ProgramImpl class ProgramD3D : public ProgramImpl
{ {
public: public:
typedef int SemanticIndexArray[gl::MAX_VERTEX_ATTRIBS];
ProgramD3D(const gl::Program::Data &data, RendererD3D *renderer); ProgramD3D(const gl::Program::Data &data, RendererD3D *renderer);
virtual ~ProgramD3D(); virtual ~ProgramD3D();
...@@ -238,12 +236,10 @@ class ProgramD3D : public ProgramImpl ...@@ -238,12 +236,10 @@ class ProgramD3D : public ProgramImpl
unsigned int getSerial() const; unsigned int getSerial() const;
void sortAttributesByLayout( const AttribIndexArray &getAttribLocationToD3DSemantics() const
const std::vector<TranslatedAttribute> &unsortedAttributes, {
int sortedSemanticIndicesOut[gl::MAX_VERTEX_ATTRIBS], return mAttribLocationToD3DSemantic;
const rx::TranslatedAttribute *sortedAttributesOut[gl::MAX_VERTEX_ATTRIBS]) const; }
const SemanticIndexArray &getSemanticIndexes() const { return mSemanticIndexes; }
const SemanticIndexArray &getAttributesByLayout() const { return mAttributesByLayout; }
void updateCachedInputLayout(const gl::State &state); void updateCachedInputLayout(const gl::State &state);
const gl::InputLayout &getCachedInputLayout() const { return mCachedInputLayout; } const gl::InputLayout &getCachedInputLayout() const { return mCachedInputLayout; }
...@@ -350,8 +346,7 @@ class ProgramD3D : public ProgramImpl ...@@ -350,8 +346,7 @@ class ProgramD3D : public ProgramImpl
D3DUniform *getD3DUniformByName(const std::string &name); D3DUniform *getD3DUniformByName(const std::string &name);
D3DUniform *getD3DUniformFromLocation(GLint location); D3DUniform *getD3DUniformFromLocation(GLint location);
void initSemanticIndex(); void initAttribLocationsToD3DSemantic();
void initAttributesByLayout();
void reset(); void reset();
void assignUniformBlockRegisters(); void assignUniformBlockRegisters();
...@@ -394,8 +389,7 @@ class ProgramD3D : public ProgramImpl ...@@ -394,8 +389,7 @@ class ProgramD3D : public ProgramImpl
// Cache for getPixelExecutableForFramebuffer // Cache for getPixelExecutableForFramebuffer
std::vector<GLenum> mPixelShaderOutputFormatCache; std::vector<GLenum> mPixelShaderOutputFormatCache;
SemanticIndexArray mSemanticIndexes; AttribIndexArray mAttribLocationToD3DSemantic;
SemanticIndexArray mAttributesByLayout;
unsigned int mSerial; unsigned int mSerial;
......
...@@ -94,6 +94,8 @@ class BufferFactoryD3D ...@@ -94,6 +94,8 @@ class BufferFactoryD3D
GLsizei instances) const = 0; GLsizei instances) const = 0;
}; };
using AttribIndexArray = std::array<int, gl::MAX_VERTEX_ATTRIBS>;
class RendererD3D : public Renderer, public BufferFactoryD3D class RendererD3D : public Renderer, public BufferFactoryD3D
{ {
public: public:
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "libANGLE/renderer/d3d/d3d11/InputLayoutCache.h" #include "libANGLE/renderer/d3d/d3d11/InputLayoutCache.h"
#include "common/BitSetIterator.h"
#include "common/utilities.h" #include "common/utilities.h"
#include "libANGLE/Program.h" #include "libANGLE/Program.h"
#include "libANGLE/VertexAttribute.h" #include "libANGLE/VertexAttribute.h"
...@@ -32,19 +33,15 @@ size_t GetReservedBufferCount(bool usesPointSpriteEmulation) ...@@ -32,19 +33,15 @@ size_t GetReservedBufferCount(bool usesPointSpriteEmulation)
return usesPointSpriteEmulation ? 1 : 0; return usesPointSpriteEmulation ? 1 : 0;
} }
gl::InputLayout GetInputLayout(const SortedAttribArray &translatedAttributes, size_t attributeCount) gl::InputLayout GetInputLayout(const std::vector<const TranslatedAttribute *> &translatedAttributes)
{ {
gl::InputLayout inputLayout(attributeCount, gl::VERTEX_FORMAT_INVALID); gl::InputLayout inputLayout(translatedAttributes.size(), gl::VERTEX_FORMAT_INVALID);
for (size_t attributeIndex = 0; attributeIndex < attributeCount; ++attributeIndex) for (size_t attributeIndex = 0; attributeIndex < translatedAttributes.size(); ++attributeIndex)
{ {
const TranslatedAttribute *translatedAttribute = translatedAttributes[attributeIndex]; const TranslatedAttribute *translatedAttribute = translatedAttributes[attributeIndex];
inputLayout[attributeIndex] = gl::GetVertexFormatType(
if (translatedAttribute->active) *translatedAttribute->attribute, translatedAttribute->currentValueType);
{
inputLayout[attributeIndex] = gl::GetVertexFormatType(
*translatedAttribute->attribute, translatedAttribute->currentValueType);
}
} }
return inputLayout; return inputLayout;
} }
...@@ -82,11 +79,12 @@ struct PackedAttribute ...@@ -82,11 +79,12 @@ struct PackedAttribute
uint8_t divisor; uint8_t divisor;
}; };
Optional<size_t> FindFirstNonInstanced(const SortedAttribArray &sortedAttributes, size_t maxIndex) Optional<size_t> FindFirstNonInstanced(
const std::vector<const TranslatedAttribute *> &currentAttributes)
{ {
for (size_t index = 0; index < maxIndex; ++index) for (size_t index = 0; index < currentAttributes.size(); ++index)
{ {
if (sortedAttributes[index]->divisor == 0) if (currentAttributes[index]->divisor == 0)
{ {
return Optional<size_t>(index); return Optional<size_t>(index);
} }
...@@ -95,6 +93,29 @@ Optional<size_t> FindFirstNonInstanced(const SortedAttribArray &sortedAttributes ...@@ -95,6 +93,29 @@ Optional<size_t> FindFirstNonInstanced(const SortedAttribArray &sortedAttributes
return Optional<size_t>::Invalid(); return Optional<size_t>::Invalid();
} }
void SortAttributesByLayout(const gl::Program *program,
const std::vector<TranslatedAttribute> &unsortedAttributes,
AttribIndexArray *sortedD3DSemanticsOut,
std::vector<const TranslatedAttribute *> *sortedAttributesOut)
{
sortedAttributesOut->clear();
const auto &locationToSemantic =
GetImplAs<ProgramD3D>(program)->getAttribLocationToD3DSemantics();
for (auto locationIndex : angle::IterateBitSet(program->getActiveAttribLocationsMask()))
{
int d3dSemantic = locationToSemantic[locationIndex];
if (sortedAttributesOut->size() <= static_cast<size_t>(d3dSemantic))
{
sortedAttributesOut->resize(d3dSemantic + 1);
}
(*sortedD3DSemanticsOut)[d3dSemantic] = d3dSemantic;
(*sortedAttributesOut)[d3dSemantic] = &unsortedAttributes[locationIndex];
}
}
} // anonymous namespace } // anonymous namespace
void InputLayoutCache::PackedAttributeLayout::addAttributeData( void InputLayoutCache::PackedAttributeLayout::addAttributeData(
...@@ -136,21 +157,19 @@ bool InputLayoutCache::PackedAttributeLayout::operator<(const PackedAttributeLay ...@@ -136,21 +157,19 @@ bool InputLayoutCache::PackedAttributeLayout::operator<(const PackedAttributeLay
return memcmp(attributeData, other.attributeData, sizeof(uint32_t) * numAttributes) < 0; return memcmp(attributeData, other.attributeData, sizeof(uint32_t) * numAttributes) < 0;
} }
InputLayoutCache::InputLayoutCache() : mUnsortedAttributesCount(0), mCacheSize(kDefaultCacheSize) InputLayoutCache::InputLayoutCache()
: mCurrentIL(nullptr),
mPointSpriteVertexBuffer(nullptr),
mPointSpriteIndexBuffer(nullptr),
mCacheSize(kDefaultCacheSize),
mCounter(0),
mDevice(nullptr),
mDeviceContext(nullptr)
{ {
mCounter = 0; mCurrentBuffers.fill(nullptr);
mDevice = NULL; mCurrentVertexStrides.fill(std::numeric_limits<UINT>::max());
mDeviceContext = NULL; mCurrentVertexOffsets.fill(std::numeric_limits<UINT>::max());
mCurrentIL = NULL; mCurrentAttributes.reserve(gl::MAX_VERTEX_ATTRIBS);
for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
{
mCurrentBuffers[i] = NULL;
mCurrentVertexStrides[i] = static_cast<UINT>(-1);
mCurrentVertexOffsets[i] = static_cast<UINT>(-1);
}
mPointSpriteVertexBuffer = NULL;
mPointSpriteIndexBuffer = NULL;
} }
InputLayoutCache::~InputLayoutCache() InputLayoutCache::~InputLayoutCache()
...@@ -180,55 +199,50 @@ void InputLayoutCache::clear() ...@@ -180,55 +199,50 @@ void InputLayoutCache::clear()
void InputLayoutCache::markDirty() void InputLayoutCache::markDirty()
{ {
mCurrentIL = NULL; mCurrentIL = nullptr;
for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
{ {
mCurrentBuffers[i] = NULL; mCurrentBuffers[i] = nullptr;
mCurrentVertexStrides[i] = static_cast<UINT>(-1); mCurrentVertexStrides[i] = static_cast<UINT>(-1);
mCurrentVertexOffsets[i] = static_cast<UINT>(-1); mCurrentVertexOffsets[i] = static_cast<UINT>(-1);
} }
mUnsortedAttributesCount = 0;
} }
gl::Error InputLayoutCache::applyVertexBuffers( gl::Error InputLayoutCache::applyVertexBuffers(
const gl::State &state,
const std::vector<TranslatedAttribute> &unsortedAttributes, const std::vector<TranslatedAttribute> &unsortedAttributes,
GLenum mode, GLenum mode,
gl::Program *program,
TranslatedIndexData *indexInfo, TranslatedIndexData *indexInfo,
GLsizei numIndicesPerInstance) GLsizei numIndicesPerInstance)
{ {
ASSERT(mDevice && mDeviceContext); ASSERT(mDevice && mDeviceContext);
gl::Program *program = state.getProgram();
ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program); ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
bool programUsesInstancedPointSprites = programD3D->usesPointSize() && programD3D->usesInstancedPointSpriteEmulation(); bool programUsesInstancedPointSprites = programD3D->usesPointSize() && programD3D->usesInstancedPointSpriteEmulation();
bool instancedPointSpritesActive = programUsesInstancedPointSprites && (mode == GL_POINTS); bool instancedPointSpritesActive = programUsesInstancedPointSprites && (mode == GL_POINTS);
SortedIndexArray sortedSemanticIndices; AttribIndexArray sortedSemanticIndices;
mSortedAttributes.fill(nullptr); SortAttributesByLayout(program, unsortedAttributes, &sortedSemanticIndices,
mUnsortedAttributesCount = unsortedAttributes.size(); &mCurrentAttributes);
programD3D->sortAttributesByLayout(unsortedAttributes, sortedSemanticIndices.data(),
mSortedAttributes.data());
// If we are using FL 9_3, make sure the first attribute is not instanced // If we are using FL 9_3, make sure the first attribute is not instanced
if (mFeatureLevel <= D3D_FEATURE_LEVEL_9_3 && !unsortedAttributes.empty()) if (mFeatureLevel <= D3D_FEATURE_LEVEL_9_3 && !mCurrentAttributes.empty())
{ {
if (mSortedAttributes[0]->divisor > 0) if (mCurrentAttributes[0]->divisor > 0)
{ {
Optional<size_t> firstNonInstancedIndex = Optional<size_t> firstNonInstancedIndex = FindFirstNonInstanced(mCurrentAttributes);
FindFirstNonInstanced(mSortedAttributes, unsortedAttributes.size());
if (firstNonInstancedIndex.valid()) if (firstNonInstancedIndex.valid())
{ {
size_t index = firstNonInstancedIndex.value(); size_t index = firstNonInstancedIndex.value();
std::swap(mSortedAttributes[0], mSortedAttributes[index]); std::swap(mCurrentAttributes[0], mCurrentAttributes[index]);
std::swap(sortedSemanticIndices[0], sortedSemanticIndices[index]); std::swap(sortedSemanticIndices[0], sortedSemanticIndices[index]);
} }
} }
} }
gl::Error error = updateInputLayout(program, mode, mSortedAttributes, sortedSemanticIndices, gl::Error error = updateInputLayout(state, mode, sortedSemanticIndices, numIndicesPerInstance);
unsortedAttributes.size(), numIndicesPerInstance);
if (error.isError()) if (error.isError())
{ {
return error; return error;
...@@ -244,14 +258,13 @@ gl::Error InputLayoutCache::applyVertexBuffers( ...@@ -244,14 +258,13 @@ gl::Error InputLayoutCache::applyVertexBuffers(
for (size_t attribIndex = 0; attribIndex < (gl::MAX_VERTEX_ATTRIBS - reservedBuffers); for (size_t attribIndex = 0; attribIndex < (gl::MAX_VERTEX_ATTRIBS - reservedBuffers);
++attribIndex) ++attribIndex)
{ {
ID3D11Buffer *buffer = NULL; ID3D11Buffer *buffer = nullptr;
UINT vertexStride = 0; UINT vertexStride = 0;
UINT vertexOffset = 0; UINT vertexOffset = 0;
const auto &attrib = *mSortedAttributes[attribIndex]; if (attribIndex < mCurrentAttributes.size())
if (attribIndex < unsortedAttributes.size() && attrib.active)
{ {
const auto &attrib = *mCurrentAttributes[attribIndex];
Buffer11 *bufferStorage = attrib.storage ? GetAs<Buffer11>(attrib.storage) : nullptr; Buffer11 *bufferStorage = attrib.storage ? GetAs<Buffer11>(attrib.storage) : nullptr;
// If indexed pointsprite emulation is active, then we need to take a less efficent code path. // If indexed pointsprite emulation is active, then we need to take a less efficent code path.
...@@ -400,8 +413,8 @@ gl::Error InputLayoutCache::applyVertexBuffers( ...@@ -400,8 +413,8 @@ gl::Error InputLayoutCache::applyVertexBuffers(
ASSERT(minDiff <= maxDiff && maxDiff < gl::MAX_VERTEX_ATTRIBS); ASSERT(minDiff <= maxDiff && maxDiff < gl::MAX_VERTEX_ATTRIBS);
mDeviceContext->IASetVertexBuffers( mDeviceContext->IASetVertexBuffers(
static_cast<UINT>(minDiff), static_cast<UINT>(maxDiff - minDiff + 1), static_cast<UINT>(minDiff), static_cast<UINT>(maxDiff - minDiff + 1),
mCurrentBuffers + minDiff, mCurrentVertexStrides + minDiff, &mCurrentBuffers[minDiff], &mCurrentVertexStrides[minDiff],
mCurrentVertexOffsets + minDiff); &mCurrentVertexOffsets[minDiff]);
} }
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
...@@ -410,32 +423,31 @@ gl::Error InputLayoutCache::applyVertexBuffers( ...@@ -410,32 +423,31 @@ gl::Error InputLayoutCache::applyVertexBuffers(
gl::Error InputLayoutCache::updateVertexOffsetsForPointSpritesEmulation(GLsizei emulatedInstanceId) gl::Error InputLayoutCache::updateVertexOffsetsForPointSpritesEmulation(GLsizei emulatedInstanceId)
{ {
size_t reservedBuffers = GetReservedBufferCount(true); size_t reservedBuffers = GetReservedBufferCount(true);
for (size_t attribIndex = 0; attribIndex < mUnsortedAttributesCount; ++attribIndex) for (size_t attribIndex = 0; attribIndex < mCurrentAttributes.size(); ++attribIndex)
{ {
const auto &attrib = *mSortedAttributes[attribIndex]; const auto &attrib = *mCurrentAttributes[attribIndex];
size_t bufferIndex = reservedBuffers + attribIndex; size_t bufferIndex = reservedBuffers + attribIndex;
if (attrib.active && attrib.divisor > 0) if (attrib.divisor > 0)
{ {
mCurrentVertexOffsets[bufferIndex] = mCurrentVertexOffsets[bufferIndex] =
attrib.offset + (attrib.stride * (emulatedInstanceId / attrib.divisor)); attrib.offset + (attrib.stride * (emulatedInstanceId / attrib.divisor));
} }
} }
mDeviceContext->IASetVertexBuffers(0, gl::MAX_VERTEX_ATTRIBS, mCurrentBuffers, mDeviceContext->IASetVertexBuffers(0, gl::MAX_VERTEX_ATTRIBS, mCurrentBuffers.data(),
mCurrentVertexStrides, mCurrentVertexOffsets); mCurrentVertexStrides.data(), mCurrentVertexOffsets.data());
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
gl::Error InputLayoutCache::updateInputLayout(gl::Program *program, gl::Error InputLayoutCache::updateInputLayout(const gl::State &state,
GLenum mode, GLenum mode,
const SortedAttribArray &sortedAttributes, const AttribIndexArray &sortedSemanticIndices,
const SortedIndexArray &sortedSemanticIndices,
size_t attribCount,
GLsizei numIndicesPerInstance) GLsizei numIndicesPerInstance)
{ {
const std::vector<sh::Attribute> &shaderAttributes = program->getAttributes(); gl::Program *program = state.getProgram();
const auto &shaderAttributes = program->getAttributes();
PackedAttributeLayout layout; PackedAttributeLayout layout;
ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program); ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
...@@ -458,25 +470,22 @@ gl::Error InputLayoutCache::updateInputLayout(gl::Program *program, ...@@ -458,25 +470,22 @@ gl::Error InputLayoutCache::updateInputLayout(gl::Program *program,
layout.flags |= PackedAttributeLayout::FLAG_INSTANCED_RENDERING_ACTIVE; layout.flags |= PackedAttributeLayout::FLAG_INSTANCED_RENDERING_ACTIVE;
} }
const auto &semanticToLocation = programD3D->getAttributesByLayout(); const auto &attribs = state.getVertexArray()->getVertexAttributes();
const auto &locationToSemantic = programD3D->getAttribLocationToD3DSemantics();
for (size_t attribIndex = 0; attribIndex < attribCount; ++attribIndex) for (unsigned long attribIndex : angle::IterateBitSet(program->getActiveAttribLocationsMask()))
{ {
const auto &attrib = *sortedAttributes[attribIndex];
int sortedIndex = sortedSemanticIndices[attribIndex];
if (!attrib.active)
continue;
gl::VertexFormatType vertexFormatType =
gl::GetVertexFormatType(*attrib.attribute, attrib.currentValueType);
// Record the type of the associated vertex shader vector in our key // Record the type of the associated vertex shader vector in our key
// This will prevent mismatched vertex shaders from using the same input layout // This will prevent mismatched vertex shaders from using the same input layout
GLenum glslElementType = GLenum glslElementType = GetGLSLAttributeType(shaderAttributes, attribIndex);
GetGLSLAttributeType(shaderAttributes, semanticToLocation[sortedIndex]);
const auto &attrib = attribs[attribIndex];
int d3dSemantic = locationToSemantic[attribIndex];
const auto &currentValue = state.getVertexAttribCurrentValue(attribIndex);
gl::VertexFormatType vertexFormatType = gl::GetVertexFormatType(attrib, currentValue.Type);
layout.addAttributeData(glslElementType, sortedIndex, vertexFormatType, attrib.divisor); layout.addAttributeData(glslElementType, d3dSemantic, vertexFormatType, attrib.divisor);
} }
ID3D11InputLayout *inputLayout = nullptr; ID3D11InputLayout *inputLayout = nullptr;
...@@ -489,9 +498,8 @@ gl::Error InputLayoutCache::updateInputLayout(gl::Program *program, ...@@ -489,9 +498,8 @@ gl::Error InputLayoutCache::updateInputLayout(gl::Program *program,
} }
else else
{ {
gl::Error error = gl::Error error = createInputLayout(sortedSemanticIndices, mode, program,
createInputLayout(sortedAttributes, sortedSemanticIndices, attribCount, mode, numIndicesPerInstance, &inputLayout);
program, numIndicesPerInstance, &inputLayout);
if (error.isError()) if (error.isError())
{ {
return error; return error;
...@@ -528,9 +536,7 @@ gl::Error InputLayoutCache::updateInputLayout(gl::Program *program, ...@@ -528,9 +536,7 @@ gl::Error InputLayoutCache::updateInputLayout(gl::Program *program,
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
gl::Error InputLayoutCache::createInputLayout(const SortedAttribArray &sortedAttributes, gl::Error InputLayoutCache::createInputLayout(const AttribIndexArray &sortedSemanticIndices,
const SortedIndexArray &sortedSemanticIndices,
size_t attribCount,
GLenum mode, GLenum mode,
gl::Program *program, gl::Program *program,
GLsizei numIndicesPerInstance, GLsizei numIndicesPerInstance,
...@@ -544,14 +550,11 @@ gl::Error InputLayoutCache::createInputLayout(const SortedAttribArray &sortedAtt ...@@ -544,14 +550,11 @@ gl::Error InputLayoutCache::createInputLayout(const SortedAttribArray &sortedAtt
unsigned int inputElementCount = 0; unsigned int inputElementCount = 0;
std::array<D3D11_INPUT_ELEMENT_DESC, gl::MAX_VERTEX_ATTRIBS> inputElements; std::array<D3D11_INPUT_ELEMENT_DESC, gl::MAX_VERTEX_ATTRIBS> inputElements;
for (size_t attribIndex = 0; attribIndex < attribCount; ++attribIndex) for (size_t attribIndex = 0; attribIndex < mCurrentAttributes.size(); ++attribIndex)
{ {
const auto &attrib = *sortedAttributes[attribIndex]; const auto &attrib = *mCurrentAttributes[attribIndex];
const int sortedIndex = sortedSemanticIndices[attribIndex]; const int sortedIndex = sortedSemanticIndices[attribIndex];
if (!attrib.active)
continue;
D3D11_INPUT_CLASSIFICATION inputClass = D3D11_INPUT_CLASSIFICATION inputClass =
attrib.divisor > 0 ? D3D11_INPUT_PER_INSTANCE_DATA : D3D11_INPUT_PER_VERTEX_DATA; attrib.divisor > 0 ? D3D11_INPUT_PER_INSTANCE_DATA : D3D11_INPUT_PER_VERTEX_DATA;
...@@ -586,21 +589,18 @@ gl::Error InputLayoutCache::createInputLayout(const SortedAttribArray &sortedAtt ...@@ -586,21 +589,18 @@ gl::Error InputLayoutCache::createInputLayout(const SortedAttribArray &sortedAtt
// simultaneously, so a non-instanced element must exist. // simultaneously, so a non-instanced element must exist.
for (size_t elementIndex = 0; elementIndex < inputElementCount; ++elementIndex) for (size_t elementIndex = 0; elementIndex < inputElementCount; ++elementIndex)
{ {
if (sortedAttributes[elementIndex]->active) // If rendering points and instanced pointsprite emulation is being used, the
// inputClass is required to be configured as per instance data
if (mode == GL_POINTS)
{ {
// If rendering points and instanced pointsprite emulation is being used, the inputElements[elementIndex].InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA;
// inputClass is required to be configured as per instance data inputElements[elementIndex].InstanceDataStepRate = 1;
if (mode == GL_POINTS) if (numIndicesPerInstance > 0 && mCurrentAttributes[elementIndex]->divisor > 0)
{ {
inputElements[elementIndex].InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA; inputElements[elementIndex].InstanceDataStepRate = numIndicesPerInstance;
inputElements[elementIndex].InstanceDataStepRate = 1;
if (numIndicesPerInstance > 0 && sortedAttributes[elementIndex]->divisor > 0)
{
inputElements[elementIndex].InstanceDataStepRate = numIndicesPerInstance;
}
} }
inputElements[elementIndex].InputSlot++;
} }
inputElements[elementIndex].InputSlot++;
} }
inputElements[inputElementCount].SemanticName = "SPRITEPOSITION"; inputElements[inputElementCount].SemanticName = "SPRITEPOSITION";
...@@ -622,7 +622,7 @@ gl::Error InputLayoutCache::createInputLayout(const SortedAttribArray &sortedAtt ...@@ -622,7 +622,7 @@ gl::Error InputLayoutCache::createInputLayout(const SortedAttribArray &sortedAtt
inputElementCount++; inputElementCount++;
} }
const gl::InputLayout &shaderInputLayout = GetInputLayout(sortedAttributes, attribCount); const gl::InputLayout &shaderInputLayout = GetInputLayout(mCurrentAttributes);
ShaderExecutableD3D *shader = nullptr; ShaderExecutableD3D *shader = nullptr;
gl::Error error = gl::Error error =
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "libANGLE/Constants.h" #include "libANGLE/Constants.h"
#include "libANGLE/Error.h" #include "libANGLE/Error.h"
#include "libANGLE/formatutils.h" #include "libANGLE/formatutils.h"
#include "libANGLE/renderer/d3d/RendererD3D.h"
namespace gl namespace gl
{ {
...@@ -34,9 +35,6 @@ struct TranslatedIndexData; ...@@ -34,9 +35,6 @@ struct TranslatedIndexData;
struct SourceIndexData; struct SourceIndexData;
class ProgramD3D; class ProgramD3D;
using SortedAttribArray = std::array<const TranslatedAttribute *, gl::MAX_VERTEX_ATTRIBS>;
using SortedIndexArray = std::array<int, gl::MAX_VERTEX_ATTRIBS>;
class InputLayoutCache : angle::NonCopyable class InputLayoutCache : angle::NonCopyable
{ {
public: public:
...@@ -47,9 +45,9 @@ class InputLayoutCache : angle::NonCopyable ...@@ -47,9 +45,9 @@ class InputLayoutCache : angle::NonCopyable
void clear(); void clear();
void markDirty(); void markDirty();
gl::Error applyVertexBuffers(const std::vector<TranslatedAttribute> &attributes, gl::Error applyVertexBuffers(const gl::State &state,
const std::vector<TranslatedAttribute> &attributes,
GLenum mode, GLenum mode,
gl::Program *program,
TranslatedIndexData *indexInfo, TranslatedIndexData *indexInfo,
GLsizei numIndicesPerInstance); GLsizei numIndicesPerInstance);
...@@ -86,15 +84,11 @@ class InputLayoutCache : angle::NonCopyable ...@@ -86,15 +84,11 @@ class InputLayoutCache : angle::NonCopyable
uint32_t attributeData[gl::MAX_VERTEX_ATTRIBS]; uint32_t attributeData[gl::MAX_VERTEX_ATTRIBS];
}; };
gl::Error updateInputLayout(gl::Program *program, gl::Error updateInputLayout(const gl::State &state,
GLenum mode, GLenum mode,
const SortedAttribArray &sortedAttributes, const AttribIndexArray &sortedSemanticIndices,
const SortedIndexArray &sortedSemanticIndices,
size_t attribCount,
GLsizei numIndicesPerInstance); GLsizei numIndicesPerInstance);
gl::Error createInputLayout(const SortedAttribArray &sortedAttributes, gl::Error createInputLayout(const AttribIndexArray &sortedSemanticIndices,
const SortedIndexArray &sortedSemanticIndices,
size_t attribCount,
GLenum mode, GLenum mode,
gl::Program *program, gl::Program *program,
GLsizei numIndicesPerInstance, GLsizei numIndicesPerInstance,
...@@ -103,11 +97,10 @@ class InputLayoutCache : angle::NonCopyable ...@@ -103,11 +97,10 @@ class InputLayoutCache : angle::NonCopyable
std::map<PackedAttributeLayout, ID3D11InputLayout *> mLayoutMap; std::map<PackedAttributeLayout, ID3D11InputLayout *> mLayoutMap;
ID3D11InputLayout *mCurrentIL; ID3D11InputLayout *mCurrentIL;
ID3D11Buffer *mCurrentBuffers[gl::MAX_VERTEX_ATTRIBS]; std::array<ID3D11Buffer *, gl::MAX_VERTEX_ATTRIBS> mCurrentBuffers;
UINT mCurrentVertexStrides[gl::MAX_VERTEX_ATTRIBS]; std::array<UINT, gl::MAX_VERTEX_ATTRIBS> mCurrentVertexStrides;
UINT mCurrentVertexOffsets[gl::MAX_VERTEX_ATTRIBS]; std::array<UINT, gl::MAX_VERTEX_ATTRIBS> mCurrentVertexOffsets;
SortedAttribArray mSortedAttributes; std::vector<const TranslatedAttribute *> mCurrentAttributes;
size_t mUnsortedAttributesCount;
ID3D11Buffer *mPointSpriteVertexBuffer; ID3D11Buffer *mPointSpriteVertexBuffer;
ID3D11Buffer *mPointSpriteIndexBuffer; ID3D11Buffer *mPointSpriteIndexBuffer;
......
...@@ -1515,8 +1515,8 @@ gl::Error Renderer11::applyVertexBuffer(const gl::State &state, ...@@ -1515,8 +1515,8 @@ gl::Error Renderer11::applyVertexBuffer(const gl::State &state,
{ {
numIndicesPerInstance = count; numIndicesPerInstance = count;
} }
return mInputLayoutCache.applyVertexBuffers(mTranslatedAttribCache, mode, state.getProgram(), return mInputLayoutCache.applyVertexBuffers(state, mTranslatedAttribCache, mode, indexInfo,
indexInfo, numIndicesPerInstance); numIndicesPerInstance);
} }
gl::Error Renderer11::applyIndexBuffer(const gl::Data &data, gl::Error Renderer11::applyIndexBuffer(const gl::Data &data,
......
...@@ -102,7 +102,7 @@ gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, ...@@ -102,7 +102,7 @@ gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device,
D3DVERTEXELEMENT9 *element = &elements[0]; D3DVERTEXELEMENT9 *element = &elements[0];
ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program); ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
const auto &semanticIndexes = programD3D->getSemanticIndexes(); const auto &semanticIndexes = programD3D->getAttribLocationToD3DSemantics();
for (size_t i = 0; i < attributes.size(); i++) for (size_t i = 0; i < attributes.size(); i++)
{ {
......
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