Image11 now generates multiple mip levels in its staging texture if a lod offset is required. TextureStorage11::updateSubresourceLevel now takes a subresource index on the source texture and copies to the correct subresource if mLodOffset is non-zero.
TRAC #13332
Signed-off-by: Jamie Madill
Signed-off-by: Shannon Woods
Author: Geoff Lang
git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1972 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/renderer/Image11.cpp b/src/libGLESv2/renderer/Image11.cpp
index b81bc1d..937ce4d 100644
--- a/src/libGLESv2/renderer/Image11.cpp
+++ b/src/libGLESv2/renderer/Image11.cpp
@@ -114,13 +114,13 @@
bool Image11::updateSurface(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
{
TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage->getStorageInstance());
- return storage11->updateSubresourceLevel(getStagingTexture(), level, 0, xoffset, yoffset, width, height);
+ return storage11->updateSubresourceLevel(getStagingTexture(), getStagingSubresource(), level, 0, xoffset, yoffset, width, height);
}
bool Image11::updateSurface(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
{
TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage->getStorageInstance());
- return storage11->updateSubresourceLevel(getStagingTexture(), level, face, xoffset, yoffset, width, height);
+ return storage11->updateSubresourceLevel(getStagingTexture(), getStagingSubresource(), level, face, xoffset, yoffset, width, height);
}
bool Image11::redefine(Renderer *renderer, GLint internalformat, GLsizei width, GLsizei height, bool forceRelease)
@@ -362,6 +362,13 @@
return mStagingTexture;
}
+unsigned int Image11::getStagingSubresource()
+{
+ createStagingTexture();
+
+ return mStagingSubresource;
+}
+
void Image11::createStagingTexture()
{
if (mStagingTexture)
@@ -370,22 +377,24 @@
}
ID3D11Texture2D *newTexture = NULL;
+ int lodOffset = 1;
const DXGI_FORMAT dxgiFormat = getDXGIFormat();
ASSERT(!d3d11::IsDepthStencilFormat(dxgiFormat)); // We should never get here for depth textures
if (mWidth != 0 && mHeight != 0)
{
- ID3D11Device *device = mRenderer->getDevice();
+ GLsizei width = mWidth;
+ GLsizei height = mHeight;
- // Round up the width and height to the nearest multiple of dimension alignment
- unsigned int dimensionAlignment = d3d11::GetTextureFormatDimensionAlignment(dxgiFormat);
- unsigned int width = mWidth + dimensionAlignment - 1 - (mWidth - 1) % dimensionAlignment;
- unsigned int height = mHeight + dimensionAlignment - 1 - (mHeight - 1) % dimensionAlignment;
+ // adjust size if needed for compressed textures
+ gl::MakeValidSize(false, d3d11::IsCompressed(dxgiFormat), &width, &height, &lodOffset);
+ ID3D11Device *device = mRenderer->getDevice();
D3D11_TEXTURE2D_DESC desc;
desc.Width = width;
desc.Height = height;
- desc.MipLevels = desc.ArraySize = 1;
+ desc.MipLevels = lodOffset + 1;
+ desc.ArraySize = 1;
desc.Format = dxgiFormat;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
@@ -405,6 +414,7 @@
}
mStagingTexture = newTexture;
+ mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1);
mDirty = false;
}
@@ -417,7 +427,7 @@
if (mStagingTexture)
{
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
- result = deviceContext->Map(mStagingTexture, 0, D3D11_MAP_WRITE, 0, map);
+ result = deviceContext->Map(mStagingTexture, mStagingSubresource, D3D11_MAP_WRITE, 0, map);
// this can fail if the device is removed (from TDR)
if (d3d11::isDeviceLostError(result))
@@ -438,7 +448,7 @@
if (mStagingTexture)
{
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
- deviceContext->Unmap(mStagingTexture, 0);
+ deviceContext->Unmap(mStagingTexture, mStagingSubresource);
}
}