tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

VertexArray11.cpp (16037B)


      1 //
      2 // Copyright 2016 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 // VertexArray11:
      7 //   Implementation of rx::VertexArray11.
      8 //
      9 
     10 #include "libANGLE/renderer/d3d/d3d11/VertexArray11.h"
     11 
     12 #include "common/bitset_utils.h"
     13 #include "libANGLE/Context.h"
     14 #include "libANGLE/renderer/d3d/IndexBuffer.h"
     15 #include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
     16 #include "libANGLE/renderer/d3d/d3d11/Context11.h"
     17 
     18 using namespace angle;
     19 
     20 namespace rx
     21 {
     22 VertexArray11::VertexArray11(const gl::VertexArrayState &data)
     23    : VertexArrayImpl(data),
     24      mAttributeStorageTypes(data.getMaxAttribs(), VertexStorageType::CURRENT_VALUE),
     25      mTranslatedAttribs(data.getMaxAttribs()),
     26      mAppliedNumViewsToDivisor(1),
     27      mCurrentElementArrayStorage(IndexStorageType::Invalid),
     28      mCachedDestinationIndexType(gl::DrawElementsType::InvalidEnum)
     29 {}
     30 
     31 VertexArray11::~VertexArray11() {}
     32 
     33 void VertexArray11::destroy(const gl::Context *context) {}
     34 
     35 // As VertexAttribPointer can modify both attribute and binding, we should also set other attributes
     36 // that are also using this binding dirty.
     37 #define ANGLE_VERTEX_DIRTY_ATTRIB_FUNC(INDEX)                                                \
     38    case gl::VertexArray::DIRTY_BIT_ATTRIB_0 + INDEX:                                        \
     39        if ((*attribBits)[INDEX][gl::VertexArray::DirtyAttribBitType::DIRTY_ATTRIB_POINTER]) \
     40        {                                                                                    \
     41            attributesToUpdate |= mState.getBindingToAttributesMask(INDEX);                  \
     42        }                                                                                    \
     43        else                                                                                 \
     44        {                                                                                    \
     45            attributesToUpdate.set(INDEX);                                                   \
     46        }                                                                                    \
     47        invalidateVertexBuffer = true;                                                       \
     48        (*attribBits)[INDEX].reset();                                                        \
     49        break;
     50 
     51 #define ANGLE_VERTEX_DIRTY_BINDING_FUNC(INDEX)                          \
     52    case gl::VertexArray::DIRTY_BIT_BINDING_0 + INDEX:                  \
     53        attributesToUpdate |= mState.getBindingToAttributesMask(INDEX); \
     54        invalidateVertexBuffer = true;                                  \
     55        (*bindingBits)[INDEX].reset();                                  \
     56        break;
     57 
     58 #define ANGLE_VERTEX_DIRTY_BUFFER_DATA_FUNC(INDEX)                      \
     59    case gl::VertexArray::DIRTY_BIT_BUFFER_DATA_0 + INDEX:              \
     60        if (mAttributeStorageTypes[INDEX] == VertexStorageType::STATIC) \
     61        {                                                               \
     62            invalidateVertexBuffer = true;                              \
     63            mAttribsToTranslate.set(INDEX);                             \
     64        }                                                               \
     65        break;
     66 
     67 angle::Result VertexArray11::syncState(const gl::Context *context,
     68                                       const gl::VertexArray::DirtyBits &dirtyBits,
     69                                       gl::VertexArray::DirtyAttribBitsArray *attribBits,
     70                                       gl::VertexArray::DirtyBindingBitsArray *bindingBits)
     71 {
     72    ASSERT(dirtyBits.any());
     73 
     74    Renderer11 *renderer         = GetImplAs<Context11>(context)->getRenderer();
     75    StateManager11 *stateManager = renderer->getStateManager();
     76 
     77    // Generate a state serial. This serial is used in the program class to validate the cached
     78    // input layout, and skip recomputation in the fast path.
     79    mCurrentStateSerial = renderer->generateSerial();
     80 
     81    bool invalidateVertexBuffer = false;
     82 
     83    gl::AttributesMask attributesToUpdate;
     84 
     85    // Make sure we trigger re-translation for static index or vertex data.
     86    for (size_t dirtyBit : dirtyBits)
     87    {
     88        switch (dirtyBit)
     89        {
     90            case gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER:
     91            case gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER_DATA:
     92            {
     93                mLastDrawElementsType.reset();
     94                mLastDrawElementsIndices.reset();
     95                mLastPrimitiveRestartEnabled.reset();
     96                mCachedIndexInfo.reset();
     97                break;
     98            }
     99 
    100                ANGLE_VERTEX_INDEX_CASES(ANGLE_VERTEX_DIRTY_ATTRIB_FUNC)
    101                ANGLE_VERTEX_INDEX_CASES(ANGLE_VERTEX_DIRTY_BINDING_FUNC)
    102                ANGLE_VERTEX_INDEX_CASES(ANGLE_VERTEX_DIRTY_BUFFER_DATA_FUNC)
    103 
    104            default:
    105                UNREACHABLE();
    106                break;
    107        }
    108    }
    109 
    110    for (size_t attribIndex : attributesToUpdate)
    111    {
    112        updateVertexAttribStorage(context, stateManager, attribIndex);
    113    }
    114 
    115    if (invalidateVertexBuffer)
    116    {
    117        // TODO(jmadill): Individual attribute invalidation.
    118        stateManager->invalidateVertexBuffer();
    119    }
    120 
    121    return angle::Result::Continue;
    122 }
    123 
    124 angle::Result VertexArray11::syncStateForDraw(const gl::Context *context,
    125                                              GLint firstVertex,
    126                                              GLsizei vertexOrIndexCount,
    127                                              gl::DrawElementsType indexTypeOrInvalid,
    128                                              const void *indices,
    129                                              GLsizei instances,
    130                                              GLint baseVertex,
    131                                              GLuint baseInstance,
    132                                              bool promoteDynamic)
    133 {
    134    Renderer11 *renderer         = GetImplAs<Context11>(context)->getRenderer();
    135    StateManager11 *stateManager = renderer->getStateManager();
    136 
    137    const gl::State &glState   = context->getState();
    138    const gl::Program *program = glState.getProgram();
    139    ASSERT(program);
    140    const gl::ProgramExecutable &executable = program->getExecutable();
    141 
    142    mAppliedNumViewsToDivisor = (program->usesMultiview() ? program->getNumViews() : 1);
    143 
    144    if (mAttribsToTranslate.any())
    145    {
    146        const gl::AttributesMask &activeLocations = executable.getActiveAttribLocationsMask();
    147        gl::AttributesMask activeDirtyAttribs     = (mAttribsToTranslate & activeLocations);
    148        if (activeDirtyAttribs.any())
    149        {
    150            ANGLE_TRY(updateDirtyAttribs(context, activeDirtyAttribs));
    151            stateManager->invalidateInputLayout();
    152        }
    153    }
    154 
    155    if (mDynamicAttribsMask.any())
    156    {
    157        const gl::AttributesMask &activeLocations = executable.getActiveAttribLocationsMask();
    158        gl::AttributesMask activeDynamicAttribs   = (mDynamicAttribsMask & activeLocations);
    159 
    160        if (activeDynamicAttribs.any())
    161        {
    162            ANGLE_TRY(updateDynamicAttribs(context, stateManager->getVertexDataManager(),
    163                                           firstVertex, vertexOrIndexCount, indexTypeOrInvalid,
    164                                           indices, instances, baseVertex, baseInstance,
    165                                           promoteDynamic, activeDynamicAttribs));
    166            stateManager->invalidateInputLayout();
    167        }
    168    }
    169 
    170    if (indexTypeOrInvalid != gl::DrawElementsType::InvalidEnum)
    171    {
    172        bool restartEnabled = context->getState().isPrimitiveRestartEnabled();
    173        if (!mLastDrawElementsType.valid() || mLastDrawElementsType.value() != indexTypeOrInvalid ||
    174            mLastDrawElementsIndices.value() != indices ||
    175            mLastPrimitiveRestartEnabled.value() != restartEnabled)
    176        {
    177            mLastDrawElementsType        = indexTypeOrInvalid;
    178            mLastDrawElementsIndices     = indices;
    179            mLastPrimitiveRestartEnabled = restartEnabled;
    180 
    181            ANGLE_TRY(updateElementArrayStorage(context, vertexOrIndexCount, indexTypeOrInvalid,
    182                                                indices, restartEnabled));
    183            stateManager->invalidateIndexBuffer();
    184        }
    185        else if (mCurrentElementArrayStorage == IndexStorageType::Dynamic)
    186        {
    187            stateManager->invalidateIndexBuffer();
    188        }
    189    }
    190 
    191    return angle::Result::Continue;
    192 }
    193 
    194 angle::Result VertexArray11::updateElementArrayStorage(const gl::Context *context,
    195                                                       GLsizei indexCount,
    196                                                       gl::DrawElementsType indexType,
    197                                                       const void *indices,
    198                                                       bool restartEnabled)
    199 {
    200    bool usePrimitiveRestartWorkaround = UsePrimitiveRestartWorkaround(restartEnabled, indexType);
    201 
    202    ANGLE_TRY(GetIndexTranslationDestType(context, indexCount, indexType, indices,
    203                                          usePrimitiveRestartWorkaround,
    204                                          &mCachedDestinationIndexType));
    205 
    206    unsigned int offset = static_cast<unsigned int>(reinterpret_cast<uintptr_t>(indices));
    207 
    208    mCurrentElementArrayStorage =
    209        ClassifyIndexStorage(context->getState(), mState.getElementArrayBuffer(), indexType,
    210                             mCachedDestinationIndexType, offset);
    211 
    212    return angle::Result::Continue;
    213 }
    214 
    215 void VertexArray11::updateVertexAttribStorage(const gl::Context *context,
    216                                              StateManager11 *stateManager,
    217                                              size_t attribIndex)
    218 {
    219    const gl::VertexAttribute &attrib = mState.getVertexAttribute(attribIndex);
    220    const gl::VertexBinding &binding  = mState.getBindingFromAttribIndex(attribIndex);
    221 
    222    VertexStorageType newStorageType = ClassifyAttributeStorage(context, attrib, binding);
    223 
    224    // Note: having an unchanged storage type doesn't mean the attribute is clean.
    225    mAttribsToTranslate.set(attribIndex, newStorageType != VertexStorageType::DYNAMIC);
    226 
    227    if (mAttributeStorageTypes[attribIndex] == newStorageType)
    228        return;
    229 
    230    mAttributeStorageTypes[attribIndex] = newStorageType;
    231    mDynamicAttribsMask.set(attribIndex, newStorageType == VertexStorageType::DYNAMIC);
    232 
    233    if (newStorageType == VertexStorageType::CURRENT_VALUE)
    234    {
    235        stateManager->invalidateCurrentValueAttrib(attribIndex);
    236    }
    237 }
    238 
    239 bool VertexArray11::hasActiveDynamicAttrib(const gl::Context *context)
    240 {
    241    const auto &activeLocations =
    242        context->getState().getProgramExecutable()->getActiveAttribLocationsMask();
    243    gl::AttributesMask activeDynamicAttribs = (mDynamicAttribsMask & activeLocations);
    244    return activeDynamicAttribs.any();
    245 }
    246 
    247 angle::Result VertexArray11::updateDirtyAttribs(const gl::Context *context,
    248                                                const gl::AttributesMask &activeDirtyAttribs)
    249 {
    250    const auto &glState  = context->getState();
    251    const auto &attribs  = mState.getVertexAttributes();
    252    const auto &bindings = mState.getVertexBindings();
    253 
    254    for (size_t dirtyAttribIndex : activeDirtyAttribs)
    255    {
    256        auto *translatedAttrib   = &mTranslatedAttribs[dirtyAttribIndex];
    257        const auto &currentValue = glState.getVertexAttribCurrentValue(dirtyAttribIndex);
    258 
    259        // Record basic attrib info
    260        translatedAttrib->attribute        = &attribs[dirtyAttribIndex];
    261        translatedAttrib->binding          = &bindings[translatedAttrib->attribute->bindingIndex];
    262        translatedAttrib->currentValueType = currentValue.Type;
    263        translatedAttrib->divisor =
    264            translatedAttrib->binding->getDivisor() * mAppliedNumViewsToDivisor;
    265 
    266        switch (mAttributeStorageTypes[dirtyAttribIndex])
    267        {
    268            case VertexStorageType::DIRECT:
    269                VertexDataManager::StoreDirectAttrib(context, translatedAttrib);
    270                break;
    271            case VertexStorageType::STATIC:
    272            {
    273                ANGLE_TRY(VertexDataManager::StoreStaticAttrib(context, translatedAttrib));
    274                break;
    275            }
    276            case VertexStorageType::CURRENT_VALUE:
    277                // Current value attribs are managed by the StateManager11.
    278                break;
    279            default:
    280                UNREACHABLE();
    281                break;
    282        }
    283 
    284        // Make sure we reset the dirty bit after the switch because STATIC can early exit.
    285        mAttribsToTranslate.reset(dirtyAttribIndex);
    286    }
    287 
    288    return angle::Result::Continue;
    289 }
    290 
    291 angle::Result VertexArray11::updateDynamicAttribs(const gl::Context *context,
    292                                                  VertexDataManager *vertexDataManager,
    293                                                  GLint firstVertex,
    294                                                  GLsizei vertexOrIndexCount,
    295                                                  gl::DrawElementsType indexTypeOrInvalid,
    296                                                  const void *indices,
    297                                                  GLsizei instances,
    298                                                  GLint baseVertex,
    299                                                  GLuint baseInstance,
    300                                                  bool promoteDynamic,
    301                                                  const gl::AttributesMask &activeDynamicAttribs)
    302 {
    303    const auto &glState  = context->getState();
    304    const auto &attribs  = mState.getVertexAttributes();
    305    const auto &bindings = mState.getVertexBindings();
    306 
    307    GLint startVertex;
    308    size_t vertexCount;
    309    ANGLE_TRY(GetVertexRangeInfo(context, firstVertex, vertexOrIndexCount, indexTypeOrInvalid,
    310                                 indices, baseVertex, &startVertex, &vertexCount));
    311 
    312    for (size_t dynamicAttribIndex : activeDynamicAttribs)
    313    {
    314        auto *dynamicAttrib      = &mTranslatedAttribs[dynamicAttribIndex];
    315        const auto &currentValue = glState.getVertexAttribCurrentValue(dynamicAttribIndex);
    316 
    317        // Record basic attrib info
    318        dynamicAttrib->attribute        = &attribs[dynamicAttribIndex];
    319        dynamicAttrib->binding          = &bindings[dynamicAttrib->attribute->bindingIndex];
    320        dynamicAttrib->currentValueType = currentValue.Type;
    321        dynamicAttrib->divisor = dynamicAttrib->binding->getDivisor() * mAppliedNumViewsToDivisor;
    322    }
    323 
    324    ANGLE_TRY(vertexDataManager->storeDynamicAttribs(context, &mTranslatedAttribs,
    325                                                     activeDynamicAttribs, startVertex, vertexCount,
    326                                                     instances, baseInstance));
    327 
    328    if (promoteDynamic)
    329    {
    330        VertexDataManager::PromoteDynamicAttribs(context, mTranslatedAttribs, activeDynamicAttribs,
    331                                                 vertexCount);
    332    }
    333 
    334    return angle::Result::Continue;
    335 }
    336 
    337 const std::vector<TranslatedAttribute> &VertexArray11::getTranslatedAttribs() const
    338 {
    339    return mTranslatedAttribs;
    340 }
    341 
    342 void VertexArray11::markAllAttributeDivisorsForAdjustment(int numViews)
    343 {
    344    if (mAppliedNumViewsToDivisor != numViews)
    345    {
    346        mAppliedNumViewsToDivisor = numViews;
    347        mAttribsToTranslate.set();
    348        // mDynamicAttribsMask may have already been set (updateVertexAttribStorage
    349        // We don't want to override DYNAMIC attribs as they will be handled separately.
    350        mAttribsToTranslate = mAttribsToTranslate ^ mDynamicAttribsMask;
    351    }
    352 }
    353 
    354 const TranslatedIndexData &VertexArray11::getCachedIndexInfo() const
    355 {
    356    ASSERT(mCachedIndexInfo.valid());
    357    return mCachedIndexInfo.value();
    358 }
    359 
    360 void VertexArray11::updateCachedIndexInfo(const TranslatedIndexData &indexInfo)
    361 {
    362    mCachedIndexInfo = indexInfo;
    363 }
    364 
    365 bool VertexArray11::isCachedIndexInfoValid() const
    366 {
    367    return mCachedIndexInfo.valid();
    368 }
    369 
    370 gl::DrawElementsType VertexArray11::getCachedDestinationIndexType() const
    371 {
    372    return mCachedDestinationIndexType;
    373 }
    374 
    375 }  // namespace rx