Esempio n. 1
0
void BufferStorage11::copyData(BufferStorage* sourceStorage, size_t size, size_t sourceOffset, size_t destOffset)
{
    BufferStorage11* sourceStorage11 = makeBufferStorage11(sourceStorage);
    if (sourceStorage11)
    {
        TypedBufferStorage11 *dest = getLatestStorage();
        if (!dest)
        {
            dest = getStagingBuffer();
        }

        TypedBufferStorage11 *source = sourceStorage11->getLatestStorage();
        if (source && dest)
        {
            // If copying to/from a pixel pack buffer, we must have a staging or
            // pack buffer partner, because other native buffers can't be mapped
            if (dest->getUsage() == BUFFER_USAGE_PIXEL_PACK && !source->isMappable())
            {
                source = sourceStorage11->getStagingBuffer();
            }
            else if (source->getUsage() == BUFFER_USAGE_PIXEL_PACK && !dest->isMappable())
            {
                dest = getStagingBuffer();
            }

            dest->copyFromStorage(source, sourceOffset, size, destOffset);
            dest->setDataRevision(dest->getDataRevision() + 1);
        }

        mSize = std::max<size_t>(mSize, destOffset + size);
    }
}
Esempio n. 2
0
void *BufferStorage11::map(GLbitfield access)
{
    ASSERT(!mMappedStorage);

    TypedBufferStorage11 *latestStorage = getLatestStorage();
    ASSERT(latestStorage);

    if (latestStorage->getUsage() == BUFFER_USAGE_PIXEL_PACK ||
        latestStorage->getUsage() == BUFFER_USAGE_STAGING)
    {
        mMappedStorage = latestStorage;
    }
    else
    {
        mMappedStorage = getStagingBuffer();
    }

    if (!mMappedStorage)
    {
        // Out-of-memory
        return NULL;
    }

    return mMappedStorage->map(access);
}
Esempio n. 3
0
BufferStorage11::TypedBufferStorage11 *BufferStorage11::getStorage(BufferUsage usage)
{
    TypedBufferStorage11 *directBuffer = NULL;
    auto directBufferIt = mTypedBuffers.find(usage);
    if (directBufferIt != mTypedBuffers.end())
    {
        directBuffer = directBufferIt->second;
    }

    if (!directBuffer)
    {
        if (usage == BUFFER_USAGE_PIXEL_PACK)
        {
            directBuffer = new PackStorage11(mRenderer);
        }
        else
        {
            // buffer is not allocated, create it
            directBuffer = new NativeBuffer11(mRenderer, usage);
        }

        mTypedBuffers.insert(std::make_pair(usage, directBuffer));
    }

    // resize buffer
    if (directBuffer->getSize() < mSize)
    {
        if (!directBuffer->resize(mSize, true))
        {
            // Out of memory error
            return NULL;
        }
    }

    TypedBufferStorage11 *latestBuffer = getLatestStorage();
    if (latestBuffer && latestBuffer->getDataRevision() > directBuffer->getDataRevision())
    {
        // if copying from a pack buffer to a non-staging native buffer, we must first
        // copy through the staging buffer, because other native buffers can't be mapped
        if (latestBuffer->getUsage() == BUFFER_USAGE_PIXEL_PACK && !directBuffer->isMappable())
        {
            NativeBuffer11 *stagingBuffer = getStagingBuffer();

            stagingBuffer->copyFromStorage(latestBuffer, 0, latestBuffer->getSize(), 0);
            directBuffer->setDataRevision(latestBuffer->getDataRevision());

            latestBuffer = stagingBuffer;
        }

        // if copyFromStorage returns true, the D3D buffer has been recreated
        // and we should update our serial
        if (directBuffer->copyFromStorage(latestBuffer, 0, latestBuffer->getSize(), 0))
        {
            updateSerial();
        }
        directBuffer->setDataRevision(latestBuffer->getDataRevision());
    }

    return directBuffer;
}
Esempio n. 4
0
void MyD3DAssets::readBuffer(ID3D11Buffer *inputBuffer, vector<BYTE> &result)
{
    ID3D11Buffer *stagingBuffer = getStagingBuffer(inputBuffer);

    context->base->CopyResource(stagingBuffer, inputBuffer);

    D3D11_MAPPED_SUBRESOURCE mappedResource;
    context->base->Map(stagingBuffer, 0, D3D11_MAP_READ, 0, &mappedResource);

    if (result.size() != mappedResource.RowPitch)
        result.resize(mappedResource.RowPitch);

    memcpy(result.data(), mappedResource.pData, mappedResource.RowPitch);

    context->base->Unmap(stagingBuffer, 0);
}
Esempio n. 5
0
void BufferStorage11::setData(const void* data, size_t size, size_t offset)
{
    size_t requiredSize = size + offset;
    mSize = std::max(mSize, requiredSize);

    if (data)
    {
        NativeBuffer11 *stagingBuffer = getStagingBuffer();

        if (!stagingBuffer)
        {
            // Out-of-memory
            return;
        }

        // Explicitly resize the staging buffer, preserving data if the new data will not
        // completely fill the buffer
        if (stagingBuffer->getSize() < requiredSize)
        {
            bool preserveData = (offset > 0);
            if (!stagingBuffer->resize(requiredSize, preserveData))
            {
                // Out-of-memory
                return;
            }
        }

        ID3D11DeviceContext *context = mRenderer->getDeviceContext();

        D3D11_MAPPED_SUBRESOURCE mappedResource;
        HRESULT result = context->Map(stagingBuffer->getNativeBuffer(), 0, D3D11_MAP_WRITE, 0, &mappedResource);
        if (FAILED(result))
        {
            return gl::error(GL_OUT_OF_MEMORY);
        }

        unsigned char *offsetBufferPointer = reinterpret_cast<unsigned char *>(mappedResource.pData) + offset;
        memcpy(offsetBufferPointer, data, size);

        context->Unmap(stagingBuffer->getNativeBuffer(), 0);

        stagingBuffer->setDataRevision(stagingBuffer->getDataRevision() + 1);
    }
}
Esempio n. 6
0
void
Driver::checkCurrentGprBuffer(ShaderStage shaderStage)
{
   const void *registerVals = nullptr;

   if (shaderStage == ShaderStage::Vertex) {
      registerVals = &mRegisters[latte::Register::SQ_ALU_CONSTANT0_256 / 4];
   } else if (shaderStage == ShaderStage::Geometry) {
      // No registers are reserved for GS
      return;
   } else if (shaderStage == ShaderStage::Pixel) {
      registerVals = &mRegisters[latte::Register::SQ_ALU_CONSTANT0_0 / 4];
   } else {
      decaf_abort("Unknown shader stage");
   }

   auto gprsBuffer = getStagingBuffer(256 * 4 * 4, vk::BufferUsageFlagBits::eUniformBuffer);
   auto mappedData = mapStagingBuffer(gprsBuffer, false);
   memcpy(mappedData, registerVals, 256 * 4 * 4);
   unmapStagingBuffer(gprsBuffer, true);

   mCurrentUniformBlocks[int(shaderStage)][0] = gprsBuffer;
}
Esempio n. 7
0
void *BufferStorage11::getData()
{
    NativeBuffer11 *stagingBuffer = getStagingBuffer();

    if (!stagingBuffer)
    {
        // Out-of-memory
        return NULL;
    }

    if (stagingBuffer->getDataRevision() > mResolvedDataRevision)
    {
        if (stagingBuffer->getSize() > mResolvedData.size())
        {
            mResolvedData.resize(stagingBuffer->getSize());
        }

        ID3D11DeviceContext *context = mRenderer->getDeviceContext();

        D3D11_MAPPED_SUBRESOURCE mappedResource;
        HRESULT result = context->Map(stagingBuffer->getNativeBuffer(), 0, D3D11_MAP_READ, 0, &mappedResource);
        if (FAILED(result))
        {
            return gl::error(GL_OUT_OF_MEMORY, (void*)NULL);
        }

        memcpy(mResolvedData.data(), mappedResource.pData, stagingBuffer->getSize());

        context->Unmap(stagingBuffer->getNativeBuffer(), 0);

        mResolvedDataRevision = stagingBuffer->getDataRevision();
    }

    mReadUsageCount = 0;

    return mResolvedData.data();
}