gl::Error Image11::copyWithoutConversion(const gl::Offset &destOffset, const gl::Box &sourceArea, const TextureHelper11 &textureHelper, UINT sourceSubResource) { // No conversion needed-- use copyback fastpath const TextureHelper11 *stagingTexture = nullptr; unsigned int stagingSubresourceIndex = 0; ANGLE_TRY(getStagingTexture(&stagingTexture, &stagingSubresourceIndex)); ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); const gl::Extents &extents = textureHelper.getExtents(); D3D11_BOX srcBox; srcBox.left = sourceArea.x; srcBox.right = sourceArea.x + sourceArea.width; srcBox.top = sourceArea.y; srcBox.bottom = sourceArea.y + sourceArea.height; srcBox.front = sourceArea.z; srcBox.back = sourceArea.z + sourceArea.depth; if (textureHelper.is2D() && textureHelper.getSampleCount() > 1) { D3D11_TEXTURE2D_DESC resolveDesc; resolveDesc.Width = extents.width; resolveDesc.Height = extents.height; resolveDesc.MipLevels = 1; resolveDesc.ArraySize = 1; resolveDesc.Format = textureHelper.getFormat(); resolveDesc.SampleDesc.Count = 1; resolveDesc.SampleDesc.Quality = 0; resolveDesc.Usage = D3D11_USAGE_DEFAULT; resolveDesc.BindFlags = 0; resolveDesc.CPUAccessFlags = 0; resolveDesc.MiscFlags = 0; d3d11::Texture2D resolveTex; ANGLE_TRY(mRenderer->allocateResource(resolveDesc, &resolveTex)); deviceContext->ResolveSubresource(resolveTex.get(), 0, textureHelper.get(), sourceSubResource, textureHelper.getFormat()); deviceContext->CopySubresourceRegion(stagingTexture->get(), stagingSubresourceIndex, destOffset.x, destOffset.y, destOffset.z, resolveTex.get(), 0, &srcBox); } else { deviceContext->CopySubresourceRegion(stagingTexture->get(), stagingSubresourceIndex, destOffset.x, destOffset.y, destOffset.z, textureHelper.get(), sourceSubResource, &srcBox); } mDirty = true; return gl::NoError(); }
gl::Error Image11::copyWithoutConversion(const gl::Offset &destOffset, const gl::Box &sourceArea, const TextureHelper11 &textureHelper, UINT sourceSubResource) { // No conversion needed-- use copyback fastpath ID3D11Resource *stagingTexture = nullptr; unsigned int stagingSubresourceIndex = 0; gl::Error error = getStagingTexture(&stagingTexture, &stagingSubresourceIndex); if (error.isError()) { return error; } ID3D11Device *device = mRenderer->getDevice(); ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); UINT subresourceAfterResolve = sourceSubResource; ID3D11Resource *srcTex = nullptr; const gl::Extents &extents = textureHelper.getExtents(); bool needResolve = (textureHelper.getTextureType() == GL_TEXTURE_2D && textureHelper.getSampleCount() > 1); if (needResolve) { D3D11_TEXTURE2D_DESC resolveDesc; resolveDesc.Width = extents.width; resolveDesc.Height = extents.height; resolveDesc.MipLevels = 1; resolveDesc.ArraySize = 1; resolveDesc.Format = textureHelper.getFormat(); resolveDesc.SampleDesc.Count = 1; resolveDesc.SampleDesc.Quality = 0; resolveDesc.Usage = D3D11_USAGE_DEFAULT; resolveDesc.BindFlags = 0; resolveDesc.CPUAccessFlags = 0; resolveDesc.MiscFlags = 0; ID3D11Texture2D *srcTex2D = NULL; HRESULT result = device->CreateTexture2D(&resolveDesc, NULL, &srcTex2D); if (FAILED(result)) { return gl::Error(GL_OUT_OF_MEMORY, "Failed to create resolve texture for Image11::copy, HRESULT: 0x%X.", result); } srcTex = srcTex2D; deviceContext->ResolveSubresource(srcTex, 0, textureHelper.getTexture2D(), sourceSubResource, textureHelper.getFormat()); subresourceAfterResolve = 0; } else { srcTex = textureHelper.getResource(); } D3D11_BOX srcBox; srcBox.left = sourceArea.x; srcBox.right = sourceArea.x + sourceArea.width; srcBox.top = sourceArea.y; srcBox.bottom = sourceArea.y + sourceArea.height; srcBox.front = sourceArea.z; srcBox.back = sourceArea.z + sourceArea.depth; deviceContext->CopySubresourceRegion(stagingTexture, stagingSubresourceIndex, destOffset.x, destOffset.y, destOffset.z, srcTex, subresourceAfterResolve, &srcBox); if (needResolve) { SafeRelease(srcTex); } mDirty = true; return gl::Error(GL_NO_ERROR); }