Esempio n. 1
0
gl::Error Image11::copyFromFramebuffer(const gl::Offset &destOffset,
                                       const gl::Rectangle &sourceArea,
                                       const gl::Framebuffer *sourceFBO)
{
    const gl::FramebufferAttachment *srcAttachment = sourceFBO->getReadColorbuffer();
    ASSERT(srcAttachment);

    const auto &d3d11Format = d3d11::GetTextureFormatInfo(srcAttachment->getInternalFormat(),
                                                          mRenderer->getRenderer11DeviceCaps());

    if (d3d11Format.formatSet->texFormat == mDXGIFormat)
    {
        RenderTargetD3D *renderTarget = nullptr;
        gl::Error error = srcAttachment->getRenderTarget(&renderTarget);
        if (error.isError())
        {
            return error;
        }

        RenderTarget11 *rt11 = GetAs<RenderTarget11>(renderTarget);
        ASSERT(rt11->getTexture());

        TextureHelper11 textureHelper =
            TextureHelper11::MakeAndReference(rt11->getTexture(), rt11->getANGLEFormat());
        unsigned int sourceSubResource = rt11->getSubresourceIndex();

        gl::Box sourceBox(sourceArea.x, sourceArea.y, 0, sourceArea.width, sourceArea.height, 1);
        return copyWithoutConversion(destOffset, sourceBox, textureHelper, sourceSubResource);
    }

    // This format requires conversion, so we must copy the texture to staging and manually convert
    // via readPixels
    D3D11_MAPPED_SUBRESOURCE mappedImage;
    gl::Error error = map(D3D11_MAP_WRITE, &mappedImage);
    if (error.isError())
    {
        return error;
    }

    // determine the offset coordinate into the destination buffer
    const auto &dxgiFormatInfo = d3d11::GetDXGIFormatSizeInfo(mDXGIFormat);
    GLsizei rowOffset          = dxgiFormatInfo.pixelBytes * destOffset.x;

    uint8_t *dataOffset = static_cast<uint8_t *>(mappedImage.pData) +
                          mappedImage.RowPitch * destOffset.y + rowOffset +
                          destOffset.z * mappedImage.DepthPitch;

    const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat);

    error = mRenderer->readFromAttachment(*srcAttachment, sourceArea, formatInfo.format,
                                          formatInfo.type, mappedImage.RowPitch,
                                          gl::PixelPackState(), dataOffset);

    unmap();
    mDirty = true;

    return error;
}
Esempio n. 2
0
gl::Error Image11::copyFromTexStorage(const gl::Context *context,
                                      const gl::ImageIndex &imageIndex,
                                      TextureStorage *source)
{
    TextureStorage11 *storage11 = GetAs<TextureStorage11>(source);

    const TextureHelper11 *textureHelper = nullptr;
    ANGLE_TRY(storage11->getResource(context, &textureHelper));

    UINT subresourceIndex = storage11->getSubresourceIndex(imageIndex);

    gl::Box sourceBox(0, 0, 0, mWidth, mHeight, mDepth);
    return copyWithoutConversion(gl::Offset(), sourceBox, *textureHelper, subresourceIndex);
}
Esempio n. 3
0
gl::Error Image11::copyFromTexStorage(const gl::ImageIndex &imageIndex, TextureStorage *source)
{
    TextureStorage11 *storage11 = GetAs<TextureStorage11>(source);

    ID3D11Resource *resource = nullptr;
    gl::Error error = storage11->getResource(&resource);
    if (error.isError())
    {
        return error;
    }

    UINT subresourceIndex         = storage11->getSubresourceIndex(imageIndex);
    TextureHelper11 textureHelper = TextureHelper11::MakeAndReference(resource);

    gl::Box sourceBox(0, 0, 0, mWidth, mHeight, mDepth);
    return copyWithoutConversion(gl::Offset(), sourceBox, textureHelper, subresourceIndex);
}
Esempio n. 4
0
gl::Error Image11::copyFromFramebuffer(const gl::Context *context,
                                       const gl::Offset &destOffset,
                                       const gl::Rectangle &sourceArea,
                                       const gl::Framebuffer *sourceFBO)
{
    const gl::FramebufferAttachment *srcAttachment = sourceFBO->getReadColorbuffer();
    ASSERT(srcAttachment);

    GLenum sourceInternalFormat = srcAttachment->getFormat().info->sizedInternalFormat;
    const auto &d3d11Format =
        d3d11::Format::Get(sourceInternalFormat, mRenderer->getRenderer11DeviceCaps());

    if (d3d11Format.texFormat == mDXGIFormat && sourceInternalFormat == mInternalFormat)
    {
        RenderTarget11 *rt11 = nullptr;
        ANGLE_TRY(srcAttachment->getRenderTarget(context, &rt11));
        ASSERT(rt11->getTexture().get());

        TextureHelper11 textureHelper  = rt11->getTexture();
        unsigned int sourceSubResource = rt11->getSubresourceIndex();

        gl::Box sourceBox(sourceArea.x, sourceArea.y, 0, sourceArea.width, sourceArea.height, 1);
        return copyWithoutConversion(destOffset, sourceBox, textureHelper, sourceSubResource);
    }

    // This format requires conversion, so we must copy the texture to staging and manually convert
    // via readPixels
    D3D11_MAPPED_SUBRESOURCE mappedImage;
    ANGLE_TRY(map(context, D3D11_MAP_WRITE, &mappedImage));

    // determine the offset coordinate into the destination buffer
    const auto &dxgiFormatInfo = d3d11::GetDXGIFormatSizeInfo(mDXGIFormat);
    GLsizei rowOffset          = dxgiFormatInfo.pixelBytes * destOffset.x;

    uint8_t *dataOffset = static_cast<uint8_t *>(mappedImage.pData) +
                          mappedImage.RowPitch * destOffset.y + rowOffset +
                          destOffset.z * mappedImage.DepthPitch;

    const gl::InternalFormat &destFormatInfo = gl::GetSizedInternalFormatInfo(mInternalFormat);
    const auto &destD3D11Format =
        d3d11::Format::Get(mInternalFormat, mRenderer->getRenderer11DeviceCaps());

    auto loadFunction = destD3D11Format.getLoadFunctions()(destFormatInfo.type);
    gl::Error error   = gl::NoError();
    if (loadFunction.requiresConversion)
    {
        size_t bufferSize = destFormatInfo.pixelBytes * sourceArea.width * sourceArea.height;
        angle::MemoryBuffer *memoryBuffer = nullptr;
        error = mRenderer->getScratchMemoryBuffer(bufferSize, &memoryBuffer);

        if (!error.isError())
        {
            GLuint memoryBufferRowPitch = destFormatInfo.pixelBytes * sourceArea.width;

            error = mRenderer->readFromAttachment(
                context, *srcAttachment, sourceArea, destFormatInfo.format, destFormatInfo.type,
                memoryBufferRowPitch, gl::PixelPackState(), memoryBuffer->data());

            loadFunction.loadFunction(sourceArea.width, sourceArea.height, 1, memoryBuffer->data(),
                                      memoryBufferRowPitch, 0, dataOffset, mappedImage.RowPitch,
                                      mappedImage.DepthPitch);
        }
    }
    else
    {
        error = mRenderer->readFromAttachment(
            context, *srcAttachment, sourceArea, destFormatInfo.format, destFormatInfo.type,
            mappedImage.RowPitch, gl::PixelPackState(), dataOffset);
    }

    unmap();
    mDirty = true;

    return error;
}