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; }
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); }
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); }
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; }