Пример #1
0
void VertexDataManager::prepareStaticBufferForAttribute(const gl::VertexAttribute &attrib,
                                                        const gl::VertexAttribCurrentValueData &currentValue) const
{
    gl::Buffer *buffer = attrib.buffer.get();

    if (buffer)
    {
        BufferD3D *bufferImpl = GetImplAs<BufferD3D>(buffer);

        // This will create the static buffer in the right circumstances
        StaticVertexBufferInterface *staticBuffer = bufferImpl->getStaticVertexBufferForAttribute(attrib);
        UNUSED_ASSERTION_VARIABLE(staticBuffer);

        // This check validates that a valid static vertex buffer was returned above
        ASSERT(!(staticBuffer &&
                 staticBuffer->getBufferSize() > 0 &&
                 !staticBuffer->lookupAttribute(attrib, NULL) &&
                 !staticBuffer->directStoragePossible(attrib, currentValue)));
    }
}
Пример #2
0
gl::Error VertexDataManager::reserveSpaceForAttrib(const gl::VertexAttribute &attrib,
                                                   const gl::VertexAttribCurrentValueData &currentValue,
                                                   GLsizei count,
                                                   GLsizei instances) const
{
    gl::Buffer *buffer = attrib.buffer.get();
    BufferD3D *bufferImpl = buffer ? GetImplAs<BufferD3D>(buffer) : NULL;
    StaticVertexBufferInterface *staticBuffer = bufferImpl ? bufferImpl->getStaticVertexBufferForAttribute(attrib) : NULL;
    VertexBufferInterface *vertexBuffer = staticBuffer ? staticBuffer : static_cast<VertexBufferInterface*>(mStreamingBuffer);

    if (!vertexBuffer->directStoragePossible(attrib, currentValue))
    {
        if (staticBuffer)
        {
            if (staticBuffer->getBufferSize() == 0)
            {
                int totalCount = ElementsInBuffer(attrib, bufferImpl->getSize());
                gl::Error error = staticBuffer->reserveVertexSpace(attrib, totalCount, 0);
                if (error.isError())
                {
                    return error;
                }
            }
        }
        else
        {
            int totalCount = StreamingBufferElementCount(attrib, count, instances);
            ASSERT(!bufferImpl || ElementsInBuffer(attrib, bufferImpl->getSize()) >= totalCount);

            gl::Error error = mStreamingBuffer->reserveVertexSpace(attrib, totalCount, instances);
            if (error.isError())
            {
                return error;
            }
        }
    }

    return gl::Error(GL_NO_ERROR);
}
Пример #3
0
gl::Error VertexDataManager::storeAttribute(const gl::VertexAttribute &attrib,
                                            const gl::VertexAttribCurrentValueData &currentValue,
                                            TranslatedAttribute *translated,
                                            GLint start,
                                            GLsizei count,
                                            GLsizei instances)
{
    gl::Buffer *buffer = attrib.buffer.get();
    ASSERT(buffer || attrib.pointer);

    BufferD3D *storage = buffer ? GetImplAs<BufferD3D>(buffer) : NULL;
    StaticVertexBufferInterface *staticBuffer = storage ? storage->getStaticVertexBufferForAttribute(attrib) : NULL;
    VertexBufferInterface *vertexBuffer = staticBuffer ? staticBuffer : static_cast<VertexBufferInterface*>(mStreamingBuffer);
    bool directStorage = vertexBuffer->directStoragePossible(attrib, currentValue);

    unsigned int streamOffset = 0;
    unsigned int outputElementSize = 0;

    // Instanced vertices do not apply the 'start' offset
    GLint firstVertexIndex = (instances > 0 && attrib.divisor > 0 ? 0 : start);

    if (directStorage)
    {
        outputElementSize = ComputeVertexAttributeStride(attrib);
        streamOffset = static_cast<unsigned int>(attrib.offset + outputElementSize * firstVertexIndex);
    }
    else if (staticBuffer)
    {
        gl::Error error = staticBuffer->getVertexBuffer()->getSpaceRequired(attrib, 1, 0, &outputElementSize);
        if (error.isError())
        {
            return error;
        }

        if (!staticBuffer->lookupAttribute(attrib, &streamOffset))
        {
            // Convert the entire buffer
            int totalCount = ElementsInBuffer(attrib, storage->getSize());
            int startIndex = attrib.offset / ComputeVertexAttributeStride(attrib);

            error = staticBuffer->storeVertexAttributes(attrib, currentValue, -startIndex, totalCount,
                                                        0, &streamOffset);

            // Each staticBuffer only contains the data for one attribute, so we know that it won't be modified again.
            // We can therefore safely unmap it here without hurting perf.
            staticBuffer->getVertexBuffer()->hintUnmapResource();

            if (error.isError())
            {
                return error;
            }
        }

        unsigned int firstElementOffset = (attrib.offset / ComputeVertexAttributeStride(attrib)) * outputElementSize;
        unsigned int startOffset = (instances == 0 || attrib.divisor == 0) ? firstVertexIndex * outputElementSize : 0;
        if (streamOffset + firstElementOffset + startOffset < streamOffset)
        {
            return gl::Error(GL_OUT_OF_MEMORY);
        }

        streamOffset += firstElementOffset + startOffset;
    }
    else
    {
        int totalCount = StreamingBufferElementCount(attrib, count, instances);
        gl::Error error = mStreamingBuffer->getVertexBuffer()->getSpaceRequired(attrib, 1, 0, &outputElementSize);
        if (error.isError())
        {
            return error;
        }

        error = mStreamingBuffer->storeVertexAttributes(attrib, currentValue, firstVertexIndex,
                                                        totalCount, instances, &streamOffset);
        if (error.isError())
        {
            return error;
        }
    }

    translated->storage = directStorage ? storage : NULL;
    translated->vertexBuffer = vertexBuffer->getVertexBuffer();
    translated->serial = directStorage ? storage->getSerial() : vertexBuffer->getSerial();
    translated->divisor = attrib.divisor;

    translated->attribute = &attrib;
    translated->currentValueType = currentValue.Type;
    translated->stride = outputElementSize;
    translated->offset = streamOffset;

    return gl::Error(GL_NO_ERROR);
}