summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp')
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp377
1 files changed, 263 insertions, 114 deletions
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp
index f44e33db18..0ff4fd3b0f 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp
@@ -20,8 +20,13 @@
namespace rx
{
-TextureStorage9::TextureStorage9(Renderer *renderer, DWORD usage)
+TextureStorage9::TextureStorage9(Renderer9 *renderer, DWORD usage)
: mTopLevel(0),
+ mMipLevels(0),
+ mTextureWidth(0),
+ mTextureHeight(0),
+ mInternalFormat(GL_NONE),
+ mTextureFormat(D3DFMT_UNKNOWN),
mRenderer(Renderer9::makeRenderer9(renderer)),
mD3DUsage(usage),
mD3DPool(mRenderer->getTexturePool(usage))
@@ -84,44 +89,52 @@ int TextureStorage9::getTopLevel() const
int TextureStorage9::getLevelCount() const
{
- return getBaseTexture() ? (getBaseTexture()->GetLevelCount() - getTopLevel()) : 0;
+ return mMipLevels - mTopLevel;
}
-TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, SwapChain9 *swapchain)
+gl::Error TextureStorage9::setData(const gl::ImageIndex &index, Image *image, const gl::Box *destBox, GLenum type,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixelData)
+{
+ UNREACHABLE();
+ return gl::Error(GL_INVALID_OPERATION);
+}
+
+TextureStorage9_2D::TextureStorage9_2D(Renderer9 *renderer, SwapChain9 *swapchain)
: TextureStorage9(renderer, D3DUSAGE_RENDERTARGET)
{
IDirect3DTexture9 *surfaceTexture = swapchain->getOffscreenTexture();
mTexture = surfaceTexture;
+ mMipLevels = surfaceTexture->GetLevelCount();
+
+ mInternalFormat = swapchain->GetBackBufferInternalFormat();
+
+ D3DSURFACE_DESC surfaceDesc;
+ surfaceTexture->GetLevelDesc(0, &surfaceDesc);
+ mTextureWidth = surfaceDesc.Width;
+ mTextureHeight = surfaceDesc.Height;
+ mTextureFormat = surfaceDesc.Format;
+
mRenderTarget = NULL;
- initializeRenderTarget();
initializeSerials(1, 1);
}
-TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels)
+TextureStorage9_2D::TextureStorage9_2D(Renderer9 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels)
: TextureStorage9(renderer, GetTextureUsage(internalformat, renderTarget))
{
mTexture = NULL;
mRenderTarget = NULL;
- // if the width or height is not positive this should be treated as an incomplete texture
- // we handle that here by skipping the d3d texture creation
- if (width > 0 && height > 0)
- {
- IDirect3DDevice9 *device = mRenderer->getDevice();
- const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat);
- d3d9::MakeValidSize(false, d3dFormatInfo.texFormat, &width, &height, &mTopLevel);
- UINT creationLevels = (levels == 0) ? 0 : mTopLevel + levels;
- HRESULT result = device->CreateTexture(width, height, creationLevels, getUsage(), d3dFormatInfo.texFormat, getPool(), &mTexture, NULL);
+ mInternalFormat = internalformat;
- if (FAILED(result))
- {
- ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- gl::error(GL_OUT_OF_MEMORY);
- }
- }
+ const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat);
+ mTextureFormat = d3dFormatInfo.texFormat;
+
+ d3d9::MakeValidSize(false, d3dFormatInfo.texFormat, &width, &height, &mTopLevel);
+ mTextureWidth = width;
+ mTextureHeight = height;
+ mMipLevels = mTopLevel + levels;
- initializeRenderTarget();
initializeSerials(getLevelCount(), 1);
}
@@ -139,104 +152,168 @@ TextureStorage9_2D *TextureStorage9_2D::makeTextureStorage9_2D(TextureStorage *s
// Increments refcount on surface.
// caller must Release() the returned surface
-IDirect3DSurface9 *TextureStorage9_2D::getSurfaceLevel(int level, bool dirty)
+gl::Error TextureStorage9_2D::getSurfaceLevel(int level, bool dirty, IDirect3DSurface9 **outSurface)
{
- IDirect3DSurface9 *surface = NULL;
+ IDirect3DBaseTexture9 *baseTexture = NULL;
+ gl::Error error = getBaseTexture(&baseTexture);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ IDirect3DTexture9 *texture = static_cast<IDirect3DTexture9*>(baseTexture);
- if (mTexture)
+ HRESULT result = texture->GetSurfaceLevel(level + mTopLevel, outSurface);
+
+ ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
{
- HRESULT result = mTexture->GetSurfaceLevel(level + mTopLevel, &surface);
- UNUSED_ASSERTION_VARIABLE(result);
- ASSERT(SUCCEEDED(result));
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to get the surface from a texture, result: 0x%X.", result);
+ }
- // With managed textures the driver needs to be informed of updates to the lower mipmap levels
- if (level + mTopLevel != 0 && isManaged() && dirty)
+ // With managed textures the driver needs to be informed of updates to the lower mipmap levels
+ if (level + mTopLevel != 0 && isManaged() && dirty)
+ {
+ texture->AddDirtyRect(NULL);
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error TextureStorage9_2D::getRenderTarget(const gl::ImageIndex &/*index*/, RenderTarget **outRT)
+{
+ if (!mRenderTarget && isRenderTarget())
+ {
+ IDirect3DSurface9 *surface = NULL;
+ gl::Error error = getSurfaceLevel(0, false, &surface);
+ if (error.isError())
{
- mTexture->AddDirtyRect(NULL);
+ return error;
}
+
+ mRenderTarget = new TextureRenderTarget9(surface, mInternalFormat, mTextureWidth, mTextureHeight, 1, 0);
}
- return surface;
+ ASSERT(outRT);
+ *outRT = mRenderTarget;
+ return gl::Error(GL_NO_ERROR);
}
-RenderTarget *TextureStorage9_2D::getRenderTarget(const gl::ImageIndex &/*index*/)
+gl::Error TextureStorage9_2D::generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex)
{
- return mRenderTarget;
+ IDirect3DSurface9 *upper = NULL;
+ gl::Error error = getSurfaceLevel(sourceIndex.mipIndex, false, &upper);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ IDirect3DSurface9 *lower = NULL;
+ error = getSurfaceLevel(destIndex.mipIndex, true, &lower);
+ if (error.isError())
+ {
+ SafeRelease(upper);
+ return error;
+ }
+
+ ASSERT(upper && lower);
+ error = mRenderer->boxFilter(upper, lower);
+
+ SafeRelease(upper);
+ SafeRelease(lower);
+
+ return error;
}
-void TextureStorage9_2D::generateMipmaps()
+gl::Error TextureStorage9_2D::getBaseTexture(IDirect3DBaseTexture9 **outTexture)
{
- // Base level must already be defined
-
- for (int level = 1; level < getLevelCount(); level++)
+ // if the width or height is not positive this should be treated as an incomplete texture
+ // we handle that here by skipping the d3d texture creation
+ if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0)
{
- IDirect3DSurface9 *upper = getSurfaceLevel(level - 1, false);
- IDirect3DSurface9 *lower = getSurfaceLevel(level, true);
+ ASSERT(mMipLevels > 0);
- if (upper != NULL && lower != NULL)
+ IDirect3DDevice9 *device = mRenderer->getDevice();
+ HRESULT result = device->CreateTexture(mTextureWidth, mTextureHeight, mMipLevels, getUsage(), mTextureFormat,
+ getPool(), &mTexture, NULL);
+
+ if (FAILED(result))
{
- mRenderer->boxFilter(upper, lower);
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D storage texture, result: 0x%X.", result);
}
-
- SafeRelease(upper);
- SafeRelease(lower);
}
-}
-IDirect3DBaseTexture9 *TextureStorage9_2D::getBaseTexture() const
-{
- return mTexture;
+ *outTexture = mTexture;
+ return gl::Error(GL_NO_ERROR);
}
-void TextureStorage9_2D::initializeRenderTarget()
+gl::Error TextureStorage9_2D::copyToStorage(TextureStorage *destStorage)
{
- ASSERT(mRenderTarget == NULL);
+ ASSERT(destStorage);
+
+ TextureStorage9_2D *dest9 = TextureStorage9_2D::makeTextureStorage9_2D(destStorage);
- if (mTexture != NULL && isRenderTarget())
+ int levels = getLevelCount();
+ for (int i = 0; i < levels; ++i)
{
- IDirect3DSurface9 *surface = getSurfaceLevel(0, false);
+ IDirect3DSurface9 *srcSurf = NULL;
+ gl::Error error = getSurfaceLevel(i, false, &srcSurf);
+ if (error.isError())
+ {
+ return error;
+ }
- mRenderTarget = new RenderTarget9(mRenderer, surface);
+ IDirect3DSurface9 *dstSurf = NULL;
+ error = dest9->getSurfaceLevel(i, true, &dstSurf);
+ if (error.isError())
+ {
+ SafeRelease(srcSurf);
+ return error;
+ }
+
+ error = mRenderer->copyToRenderTarget(dstSurf, srcSurf, isManaged());
+
+ SafeRelease(srcSurf);
+ SafeRelease(dstSurf);
+
+ if (error.isError())
+ {
+ return error;
+ }
}
+
+ return gl::Error(GL_NO_ERROR);
}
-TextureStorage9_Cube::TextureStorage9_Cube(Renderer *renderer, GLenum internalformat, bool renderTarget, int size, int levels)
+TextureStorage9_Cube::TextureStorage9_Cube(Renderer9 *renderer, GLenum internalformat, bool renderTarget, int size, int levels)
: TextureStorage9(renderer, GetTextureUsage(internalformat, renderTarget))
{
mTexture = NULL;
- for (int i = 0; i < 6; ++i)
+ for (int i = 0; i < CUBE_FACE_COUNT; ++i)
{
mRenderTarget[i] = NULL;
}
- // if the size is not positive this should be treated as an incomplete texture
- // we handle that here by skipping the d3d texture creation
- if (size > 0)
- {
- IDirect3DDevice9 *device = mRenderer->getDevice();
- int height = size;
- const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat);
- d3d9::MakeValidSize(false, d3dFormatInfo.texFormat, &size, &height, &mTopLevel);
- UINT creationLevels = (levels == 0) ? 0 : mTopLevel + levels;
+ mInternalFormat = internalformat;
- HRESULT result = device->CreateCubeTexture(size, creationLevels, getUsage(), d3dFormatInfo.texFormat, getPool(), &mTexture, NULL);
+ const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat);
+ mTextureFormat = d3dFormatInfo.texFormat;
- if (FAILED(result))
- {
- ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- gl::error(GL_OUT_OF_MEMORY);
- }
- }
+ int height = size;
+ d3d9::MakeValidSize(false, d3dFormatInfo.texFormat, &size, &height, &mTopLevel);
+ mTextureWidth = size;
+ mTextureHeight = size;
+ mMipLevels = mTopLevel + levels;
- initializeRenderTarget();
- initializeSerials(getLevelCount() * 6, 6);
+ initializeSerials(getLevelCount() * CUBE_FACE_COUNT, CUBE_FACE_COUNT);
}
TextureStorage9_Cube::~TextureStorage9_Cube()
{
SafeRelease(mTexture);
- for (int i = 0; i < 6; ++i)
+ for (int i = 0; i < CUBE_FACE_COUNT; ++i)
{
SafeDelete(mRenderTarget[i]);
}
@@ -250,74 +327,146 @@ TextureStorage9_Cube *TextureStorage9_Cube::makeTextureStorage9_Cube(TextureStor
// Increments refcount on surface.
// caller must Release() the returned surface
-IDirect3DSurface9 *TextureStorage9_Cube::getCubeMapSurface(GLenum faceTarget, int level, bool dirty)
+gl::Error TextureStorage9_Cube::getCubeMapSurface(GLenum faceTarget, int level, bool dirty, IDirect3DSurface9 **outSurface)
{
- IDirect3DSurface9 *surface = NULL;
+ IDirect3DBaseTexture9 *baseTexture = NULL;
+ gl::Error error = getBaseTexture(&baseTexture);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ IDirect3DCubeTexture9 *texture = static_cast<IDirect3DCubeTexture9*>(baseTexture);
- if (mTexture)
+ D3DCUBEMAP_FACES face = gl_d3d9::ConvertCubeFace(faceTarget);
+ HRESULT result = texture->GetCubeMapSurface(face, level + mTopLevel, outSurface);
+
+ ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
{
- D3DCUBEMAP_FACES face = gl_d3d9::ConvertCubeFace(faceTarget);
- HRESULT result = mTexture->GetCubeMapSurface(face, level + mTopLevel, &surface);
- UNUSED_ASSERTION_VARIABLE(result);
- ASSERT(SUCCEEDED(result));
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to get the surface from a texture, result: 0x%X.", result);
+ }
- // With managed textures the driver needs to be informed of updates to the lower mipmap levels
- if (level != 0 && isManaged() && dirty)
+ // With managed textures the driver needs to be informed of updates to the lower mipmap levels
+ if (level != 0 && isManaged() && dirty)
+ {
+ texture->AddDirtyRect(face, NULL);
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error TextureStorage9_Cube::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
+{
+ ASSERT(outRT);
+ ASSERT(index.mipIndex == 0);
+ ASSERT(index.layerIndex >= 0 && index.layerIndex < CUBE_FACE_COUNT);
+
+ if (mRenderTarget[index.layerIndex] == NULL && isRenderTarget())
+ {
+ IDirect3DSurface9 *surface = NULL;
+ gl::Error error = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + index.layerIndex, 0, false, &surface);
+ if (error.isError())
{
- mTexture->AddDirtyRect(face, NULL);
+ return error;
}
+
+ mRenderTarget[index.layerIndex] = new TextureRenderTarget9(surface, mInternalFormat, mTextureWidth, mTextureHeight, 1, 0);
}
- return surface;
+ *outRT = mRenderTarget[index.layerIndex];
+ return gl::Error(GL_NO_ERROR);
}
-RenderTarget *TextureStorage9_Cube::getRenderTarget(const gl::ImageIndex &index)
+gl::Error TextureStorage9_Cube::generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex)
{
- return mRenderTarget[index.layerIndex];
+ IDirect3DSurface9 *upper = NULL;
+ gl::Error error = getCubeMapSurface(sourceIndex.type, sourceIndex.mipIndex, false, &upper);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ IDirect3DSurface9 *lower = NULL;
+ error = getCubeMapSurface(destIndex.type, destIndex.mipIndex, true, &lower);
+ if (error.isError())
+ {
+ SafeRelease(upper);
+ return error;
+ }
+
+ ASSERT(upper && lower);
+ error = mRenderer->boxFilter(upper, lower);
+
+ SafeRelease(upper);
+ SafeRelease(lower);
+
+ return error;
}
-void TextureStorage9_Cube::generateMipmaps()
+gl::Error TextureStorage9_Cube::getBaseTexture(IDirect3DBaseTexture9 **outTexture)
{
- // Base level must already be defined
-
- for (int faceIndex = 0; faceIndex < 6; faceIndex++)
+ // if the size is not positive this should be treated as an incomplete texture
+ // we handle that here by skipping the d3d texture creation
+ if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0)
{
- for (int level = 1; level < getLevelCount(); level++)
- {
- IDirect3DSurface9 *upper = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level - 1, false);
- IDirect3DSurface9 *lower = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level, true);
+ ASSERT(mMipLevels > 0);
+ ASSERT(mTextureWidth == mTextureHeight);
- if (upper != NULL && lower != NULL)
- {
- mRenderer->boxFilter(upper, lower);
- }
+ IDirect3DDevice9 *device = mRenderer->getDevice();
+ HRESULT result = device->CreateCubeTexture(mTextureWidth, mMipLevels, getUsage(), mTextureFormat, getPool(),
+ &mTexture, NULL);
- SafeRelease(upper);
- SafeRelease(lower);
+ if (FAILED(result))
+ {
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create cube storage texture, result: 0x%X.", result);
}
}
-}
-IDirect3DBaseTexture9 *TextureStorage9_Cube::getBaseTexture() const
-{
- return mTexture;
+ *outTexture = mTexture;
+ return gl::Error(GL_NO_ERROR);
}
-void TextureStorage9_Cube::initializeRenderTarget()
+gl::Error TextureStorage9_Cube::copyToStorage(TextureStorage *destStorage)
{
- if (mTexture != NULL && isRenderTarget())
- {
- IDirect3DSurface9 *surface = NULL;
+ ASSERT(destStorage);
+
+ TextureStorage9_Cube *dest9 = TextureStorage9_Cube::makeTextureStorage9_Cube(destStorage);
- for (int i = 0; i < 6; ++i)
+ int levels = getLevelCount();
+ for (int f = 0; f < CUBE_FACE_COUNT; f++)
+ {
+ for (int i = 0; i < levels; i++)
{
- ASSERT(mRenderTarget[i] == NULL);
+ IDirect3DSurface9 *srcSurf = NULL;
+ gl::Error error = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, false, &srcSurf);
+ if (error.isError())
+ {
+ return error;
+ }
- surface = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, false);
+ IDirect3DSurface9 *dstSurf = NULL;
+ error = dest9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, true, &dstSurf);
+ if (error.isError())
+ {
+ SafeRelease(srcSurf);
+ return error;
+ }
+
+ error = mRenderer->copyToRenderTarget(dstSurf, srcSurf, isManaged());
- mRenderTarget[i] = new RenderTarget9(mRenderer, surface);
+ SafeRelease(srcSurf);
+ SafeRelease(dstSurf);
+
+ if (error.isError())
+ {
+ return error;
+ }
}
}
+
+ return gl::Error(GL_NO_ERROR);
}
-} \ No newline at end of file
+}