Moves TextureStorage class to TextureStorage9, mostly.

TRAC #22300

Author: Shannon Woods
Signed-off-by: Geoff Lang
Signed-off-by: Daniel Koch

git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1612 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/build_angle.gypi b/src/build_angle.gypi
index addf12d..be48066 100644
--- a/src/build_angle.gypi
+++ b/src/build_angle.gypi
@@ -298,6 +298,8 @@
             'libGLESv2/renderer/SwapChain11.h',
             'libGLESv2/renderer/TextureStorage.cpp',
             'libGLESv2/renderer/TextureStorage.h',
+            'libGLESv2/renderer/TextureStorage9.cpp',
+            'libGLESv2/renderer/TextureStorage9.h',
             'libGLESv2/renderer/VertexBuffer.cpp',
             'libGLESv2/renderer/VertexBuffer.h',
             'libGLESv2/renderer/VertexBuffer9.cpp',
diff --git a/src/libGLESv2/Texture.cpp b/src/libGLESv2/Texture.cpp
index 10736be..a110e26 100644
--- a/src/libGLESv2/Texture.cpp
+++ b/src/libGLESv2/Texture.cpp
@@ -857,6 +857,7 @@
     {
         return NULL;
     }
+
     return mTexStorage->getRenderTarget();
 }
 
diff --git a/src/libGLESv2/libGLESv2.vcxproj b/src/libGLESv2/libGLESv2.vcxproj
index 5350bb7..25a9368 100644
--- a/src/libGLESv2/libGLESv2.vcxproj
+++ b/src/libGLESv2/libGLESv2.vcxproj
@@ -267,6 +267,7 @@
     <ClCompile Include="renderer\SwapChain11.cpp" />

     <ClCompile Include="renderer\SwapChain9.cpp" />

     <ClCompile Include="renderer\TextureStorage.cpp" />

+    <ClCompile Include="renderer\TextureStorage9.cpp" />

     <ClCompile Include="renderer\VertexBuffer.cpp" />

     <ClCompile Include="renderer\VertexBuffer11.cpp" />

     <ClCompile Include="renderer\VertexBuffer9.cpp" />

@@ -325,6 +326,7 @@
     <ClInclude Include="renderer\SwapChain11.h" />

     <ClInclude Include="renderer\SwapChain9.h" />

     <ClInclude Include="renderer\TextureStorage.h" />

+    <ClInclude Include="renderer\TextureStorage9.h" />

     <ClInclude Include="renderer\VertexBuffer.h" />

     <ClInclude Include="renderer\VertexBuffer11.h" />

     <ClInclude Include="renderer\VertexBuffer9.h" />

@@ -357,5 +359,5 @@
   </ItemGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

   <ImportGroup Label="ExtensionTargets">

-  </ImportGroup>
+  </ImportGroup>

 </Project>
diff --git a/src/libGLESv2/libGLESv2.vcxproj.filters b/src/libGLESv2/libGLESv2.vcxproj.filters
index 0cd9b68..140bc1a 100644
--- a/src/libGLESv2/libGLESv2.vcxproj.filters
+++ b/src/libGLESv2/libGLESv2.vcxproj.filters
@@ -170,6 +170,9 @@
     <ClCompile Include="Uniform.cpp">

       <Filter>Source Files</Filter>

     </ClCompile>
+    <ClCompile Include="renderer\TextureStorage9.cpp">

+      <Filter>Renderer</Filter>

+    </ClCompile>

   </ItemGroup>

   <ItemGroup>

     <ClInclude Include="BinaryStream.h">

@@ -349,6 +352,9 @@
     <ClInclude Include="Uniform.h">

       <Filter>Header Files</Filter>

     </ClInclude>
+    <ClInclude Include="renderer\TextureStorage9.h">

+      <Filter>Renderer</Filter>

+    </ClInclude>

   </ItemGroup>

   <ItemGroup>

     <None Include="libGLESv2.def">

@@ -358,4 +364,4 @@
   <ItemGroup>

     <ResourceCompile Include="libGLESv2.rc" />

   </ItemGroup>

-</Project>
\ No newline at end of file
+</Project>
diff --git a/src/libGLESv2/renderer/Blit.cpp b/src/libGLESv2/renderer/Blit.cpp
index 4da5fc7..978426f 100644
--- a/src/libGLESv2/renderer/Blit.cpp
+++ b/src/libGLESv2/renderer/Blit.cpp
@@ -13,8 +13,8 @@
 #include "libGLESv2/main.h"
 #include "libGLESv2/utilities.h"
 #include "libGLESv2/renderer/renderer9_utils.h" // D3D9_REPLACE
-#include "libGLESv2/renderer/TextureStorage.h"
-#include "libGLESv2/renderer/RenderTarget9.h"
+#include "libGLESv2/renderer/TextureStorage9.h" // D3D9_REPLACE
+#include "libGLESv2/renderer/RenderTarget9.h"   // D3D9_REPLACE
 #include "libGLESv2/Framebuffer.h"
 
 namespace
@@ -236,7 +236,8 @@
         return error(GL_OUT_OF_MEMORY, false);
     }
 
-    IDirect3DSurface9 *destSurface = storage->getSurfaceLevel(level, true);
+    TextureStorage2D9 *storage9 = TextureStorage2D9::makeTextureStorage2D9(storage->getStorageInterface());
+    IDirect3DSurface9 *destSurface = storage9->getSurfaceLevel(level, true);
     bool result = false;
         
     if (destSurface)
@@ -272,7 +273,8 @@
         return error(GL_OUT_OF_MEMORY, false);
     }
 
-    IDirect3DSurface9 *destSurface = storage->getCubeMapSurface(target, level, true);
+    TextureStorageCubeMap9 *storage9 = TextureStorageCubeMap9::makeTextureStorageCubeMap9(storage->getStorageInterface());
+    IDirect3DSurface9 *destSurface = storage9->getCubeMapSurface(target, level, true);
     bool result = false;
 
     if (destSurface)
diff --git a/src/libGLESv2/renderer/Image9.cpp b/src/libGLESv2/renderer/Image9.cpp
index b106659..e54e378 100644
--- a/src/libGLESv2/renderer/Image9.cpp
+++ b/src/libGLESv2/renderer/Image9.cpp
@@ -17,6 +17,7 @@
 #include "libGLESv2/Texture.h"
 #include "libGLESv2/Framebuffer.h"
 #include "libGLESv2/renderer/RenderTarget9.h"
+#include "libGLESv2/renderer/TextureStorage9.h"
 
 #include "libGLESv2/renderer/renderer9_utils.h"
 #include "libGLESv2/renderer/generatemip.h"
@@ -239,7 +240,7 @@
 
 bool Image9::isRenderableFormat() const
 {    
-    return TextureStorage::IsTextureFormatRenderable(getD3DFormat());
+    return TextureStorage9::IsTextureFormatRenderable(getD3DFormat());
 }
 
 D3DFORMAT Image9::getD3DFormat() const
@@ -260,12 +261,14 @@
 
 void Image9::setManagedSurface(TextureStorage2D *storage, int level)
 {
-    setManagedSurface(storage->getSurfaceLevel(level, false));
+    TextureStorage2D9 *storage9 = TextureStorage2D9::makeTextureStorage2D9(storage->getStorageInterface());
+    setManagedSurface(storage9->getSurfaceLevel(level, false));
 }
 
 void Image9::setManagedSurface(TextureStorageCubeMap *storage, int face, int level)
 {
-    setManagedSurface(storage->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, false));
+    TextureStorageCubeMap9 *storage9 = TextureStorageCubeMap9::makeTextureStorageCubeMap9(storage->getStorageInterface());
+    setManagedSurface(storage9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, false));
 }
 
 void Image9::setManagedSurface(IDirect3DSurface9 *surface)
@@ -290,13 +293,15 @@
 bool Image9::updateSurface(TextureStorage2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
 {
     ASSERT(getSurface() != NULL);
-    return updateSurface(storage->getSurfaceLevel(level, true), xoffset, yoffset, width, height);
+    TextureStorage2D9 *storage9 = TextureStorage2D9::makeTextureStorage2D9(storage->getStorageInterface());
+    return updateSurface(storage9->getSurfaceLevel(level, true), xoffset, yoffset, width, height);
 }
 
 bool Image9::updateSurface(TextureStorageCubeMap *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
 {
     ASSERT(getSurface() != NULL);
-    return updateSurface(storage->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, true), xoffset, yoffset, width, height);
+    TextureStorageCubeMap9 *storage9 = TextureStorageCubeMap9::makeTextureStorageCubeMap9(storage->getStorageInterface());
+    return updateSurface(storage9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, true), xoffset, yoffset, width, height);
 }
 
 bool Image9::updateSurface(IDirect3DSurface9 *destSurface, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
diff --git a/src/libGLESv2/renderer/Renderer9.cpp b/src/libGLESv2/renderer/Renderer9.cpp
index b974965..b2a3b4a 100644
--- a/src/libGLESv2/renderer/Renderer9.cpp
+++ b/src/libGLESv2/renderer/Renderer9.cpp
@@ -20,7 +20,7 @@
 #include "libGLESv2/renderer/renderer9_utils.h"
 #include "libGLESv2/renderer/ShaderExecutable9.h"
 #include "libGLESv2/renderer/SwapChain9.h"
-#include "libGLESv2/renderer/TextureStorage.h"
+#include "libGLESv2/renderer/TextureStorage9.h"
 #include "libGLESv2/renderer/Image9.h"
 #include "libGLESv2/renderer/Blit.h"
 #include "libGLESv2/renderer/RenderTarget9.h"
@@ -637,7 +637,8 @@
         TextureStorage *texStorage = texture->getNativeTexture();
         if (texStorage)
         {
-            d3dTexture = texStorage->getBaseTexture();
+            TextureStorage9 *storage9 = TextureStorage9::makeTextureStorage9(texStorage->getStorageInterface());
+            d3dTexture = storage9->getBaseTexture();
         }
         // If we get NULL back from getBaseTexture here, something went wrong
         // in the texture class and we're unexpectedly missing the d3d texture
@@ -2375,13 +2376,16 @@
 
     if (source && dest)
     {
-        int levels = source->levelCount();
+        TextureStorage2D9 *source9 = TextureStorage2D9::makeTextureStorage2D9(source->getStorageInterface());
+        TextureStorage2D9 *dest9 = TextureStorage2D9::makeTextureStorage2D9(dest->getStorageInterface());
+
+        int levels = source9->levelCount();
         for (int i = 0; i < levels; ++i)
         {
-            IDirect3DSurface9 *srcSurf = source->getSurfaceLevel(i, false);
-            IDirect3DSurface9 *dstSurf = dest->getSurfaceLevel(i, false);
+            IDirect3DSurface9 *srcSurf = source9->getSurfaceLevel(i, false);
+            IDirect3DSurface9 *dstSurf = dest9->getSurfaceLevel(i, false);
             
-            result = copyToRenderTarget(dstSurf, srcSurf, source->isManaged());
+            result = copyToRenderTarget(dstSurf, srcSurf, source9->isManaged());
 
             if (srcSurf) srcSurf->Release();
             if (dstSurf) dstSurf->Release();
@@ -2400,15 +2404,17 @@
 
     if (source && dest)
     {
-        int levels = source->levelCount();
+        TextureStorageCubeMap9 *source9 = TextureStorageCubeMap9::makeTextureStorageCubeMap9(source->getStorageInterface());
+        TextureStorageCubeMap9 *dest9 = TextureStorageCubeMap9::makeTextureStorageCubeMap9(dest->getStorageInterface());
+        int levels = source9->levelCount();
         for (int f = 0; f < 6; f++)
         {
             for (int i = 0; i < levels; i++)
             {
-                IDirect3DSurface9 *srcSurf = source->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, false);
-                IDirect3DSurface9 *dstSurf = dest->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, true);
+                IDirect3DSurface9 *srcSurf = source9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, false);
+                IDirect3DSurface9 *dstSurf = dest9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, true);
 
-                result = copyToRenderTarget(dstSurf, srcSurf, source->isManaged());
+                result = copyToRenderTarget(dstSurf, srcSurf, source9->isManaged());
 
                 if (srcSurf) srcSurf->Release();
                 if (dstSurf) dstSurf->Release();
diff --git a/src/libGLESv2/renderer/TextureStorage.cpp b/src/libGLESv2/renderer/TextureStorage.cpp
index 7b5d0f5..9e001f3 100644
--- a/src/libGLESv2/renderer/TextureStorage.cpp
+++ b/src/libGLESv2/renderer/TextureStorage.cpp
@@ -6,10 +6,11 @@
 
 // TextureStorage.cpp: Implements the abstract rx::TextureStorage class and its concrete derived
 // classes TextureStorage2D and TextureStorageCubeMap, which act as the interface to the
-// D3D-side texture.
+// GPU-side texture.
 
 #include "libGLESv2/main.h"
 #include "libGLESv2/renderer/TextureStorage.h"
+#include "libGLESv2/renderer/TextureStorage9.h"
 #include "libGLESv2/renderer/SwapChain9.h"
 #include "libGLESv2/renderer/Blit.h"
 #include "libGLESv2/renderer/RenderTarget9.h"
@@ -21,12 +22,8 @@
 {
 unsigned int TextureStorage::mCurrentTextureSerial = 1;
 
-TextureStorage::TextureStorage(Renderer *renderer, DWORD usage)
-    : mLodOffset(0),
-      mRenderer(Renderer9::makeRenderer9(renderer)),
-      mD3DUsage(usage),
-      mD3DPool(mRenderer->getTexturePool(usage)),
-      mTextureSerial(issueTextureSerial()),
+TextureStorage::TextureStorage()
+    : mTextureSerial(issueTextureSerial()),
       mInterface(NULL)
 {
 }
@@ -36,65 +33,15 @@
     delete mInterface;
 }
 
-DWORD TextureStorage::GetTextureUsage(D3DFORMAT d3dfmt, GLenum glusage, bool forceRenderable)
-{
-    DWORD d3dusage = 0;
-
-    if (d3dfmt == D3DFMT_INTZ)
-    {
-        d3dusage |= D3DUSAGE_DEPTHSTENCIL;
-    }
-    else if(forceRenderable || (TextureStorage::IsTextureFormatRenderable(d3dfmt) && (glusage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE)))
-    {
-        d3dusage |= D3DUSAGE_RENDERTARGET;
-    }
-    return d3dusage;
-}
-
-bool TextureStorage::IsTextureFormatRenderable(D3DFORMAT format)
-{
-    if (format == D3DFMT_INTZ)
-    {
-        return true;
-    }
-    switch(format)
-    {
-      case D3DFMT_L8:
-      case D3DFMT_A8L8:
-      case D3DFMT_DXT1:
-      case D3DFMT_DXT3:
-      case D3DFMT_DXT5:
-        return false;
-      case D3DFMT_A8R8G8B8:
-      case D3DFMT_X8R8G8B8:
-      case D3DFMT_A16B16G16R16F:
-      case D3DFMT_A32B32G32R32F:
-        return true;
-      default:
-        UNREACHABLE();
-    }
-
-    return false;
-}
-
 bool TextureStorage::isRenderTarget() const
 {
-    return (mD3DUsage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL)) != 0;
+    return mInterface->isRenderTarget();
 }
 
+
 bool TextureStorage::isManaged() const
 {
-    return (mD3DPool == D3DPOOL_MANAGED);
-}
-
-D3DPOOL TextureStorage::getPool() const
-{
-    return mD3DPool;
-}
-
-DWORD TextureStorage::getUsage() const
-{
-    return mD3DUsage;
+    return mInterface->isManaged();
 }
 
 unsigned int TextureStorage::getTextureSerial() const
@@ -109,99 +56,41 @@
 
 int TextureStorage::getLodOffset() const
 {
-    return mLodOffset;
+    return mInterface->getLodOffset();
 }
 
+
 int TextureStorage::levelCount()
 {
-    return getBaseTexture() ? getBaseTexture()->GetLevelCount() - getLodOffset() : 0;
+    return mInterface->levelCount();
 }
 
-TextureStorage2D::TextureStorage2D(Renderer *renderer, rx::SwapChain9 *swapchain) : TextureStorage(renderer, D3DUSAGE_RENDERTARGET), mRenderTargetSerial(gl::RenderbufferStorage::issueSerial())
+TextureStorage2D::TextureStorage2D(Renderer *renderer, SwapChain9 *swapchain) 
+    : mRenderTargetSerial(gl::RenderbufferStorage::issueSerial())
 {
-    IDirect3DTexture9 *surfaceTexture = swapchain->getOffscreenTexture();
-    mTexture = surfaceTexture;
-
-    initializeRenderTarget();
+    TextureStorage2D9 *newInterface = new TextureStorage2D9(renderer, swapchain);
+    mInterface = newInterface;
 }
 
 TextureStorage2D::TextureStorage2D(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height)
-    : TextureStorage(renderer, GetTextureUsage(Renderer9::makeRenderer9(renderer)->ConvertTextureInternalFormat(internalformat), usage, forceRenderable)),
-      mRenderTargetSerial(gl::RenderbufferStorage::issueSerial())
+    : mRenderTargetSerial(gl::RenderbufferStorage::issueSerial())
 {
-    mTexture = 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(); // D3D9_REPLACE
-        gl::MakeValidSize(false, gl::IsCompressed(internalformat), &width, &height, &mLodOffset);
-        HRESULT result = device->CreateTexture(width, height, levels ? levels + mLodOffset : 0, getUsage(),
-                                               mRenderer->ConvertTextureInternalFormat(internalformat), getPool(), &mTexture, NULL);
-
-        if (FAILED(result))
-        {
-            ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
-            error(GL_OUT_OF_MEMORY);
-        }
-    }
-
-    initializeRenderTarget();
+    TextureStorage2D9 *newInterface = new TextureStorage2D9(renderer, levels, internalformat, usage, forceRenderable, width, height); // D3D9_REPLACE
+    mInterface = newInterface;
 }
 
 TextureStorage2D::~TextureStorage2D()
 {
-    if (mTexture)
-    {
-        mTexture->Release();
-    }
-
-    delete mRenderTarget;
-}
-
-// Increments refcount on surface.
-// caller must Release() the returned surface
-IDirect3DSurface9 *TextureStorage2D::getSurfaceLevel(int level, bool dirty)
-{
-    IDirect3DSurface9 *surface = NULL;
-
-    if (mTexture)
-    {
-        HRESULT result = mTexture->GetSurfaceLevel(level + mLodOffset, &surface);
-        ASSERT(SUCCEEDED(result));
-
-        // With managed textures the driver needs to be informed of updates to the lower mipmap levels
-        if (level != 0 && isManaged() && dirty)
-        {
-            mTexture->AddDirtyRect(NULL);
-        }
-    }
-
-    return surface;
 }
 
 RenderTarget *TextureStorage2D::getRenderTarget() const
 {
-    return mRenderTarget;
+    return mInterface->getRenderTarget();
 }
 
 void TextureStorage2D::generateMipmap(int level)
 {
-    IDirect3DSurface9 *upper = getSurfaceLevel(level - 1, false);
-    IDirect3DSurface9 *lower = getSurfaceLevel(level, true);
-
-    if (upper != NULL && lower != NULL)
-    {
-        mRenderer->boxFilter(upper, lower);
-    }
-
-    if (upper != NULL) upper->Release();
-    if (lower != NULL) lower->Release();
-}
-
-IDirect3DBaseTexture9 *TextureStorage2D::getBaseTexture() const
-{
-    return mTexture;
+    mInterface->generateMipmap(level);
 }
 
 unsigned int TextureStorage2D::getRenderTargetSerial(GLenum target) const
@@ -209,102 +98,25 @@
     return mRenderTargetSerial;
 }
 
-void TextureStorage2D::initializeRenderTarget()
-{
-    if (mTexture != NULL && isRenderTarget())
-    {
-        IDirect3DSurface9 *surface = getSurfaceLevel(0, false);
-
-        mRenderTarget = new RenderTarget9(mRenderer, surface);
-    }
-    else
-    {
-        mRenderTarget = NULL;
-    }
-}
-
 TextureStorageCubeMap::TextureStorageCubeMap(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size)
-    : TextureStorage(renderer, GetTextureUsage(Renderer9::makeRenderer9(renderer)->ConvertTextureInternalFormat(internalformat), usage, forceRenderable)),
-      mFirstRenderTargetSerial(gl::RenderbufferStorage::issueCubeSerials())
+    : mFirstRenderTargetSerial(gl::RenderbufferStorage::issueCubeSerials())
 {
-    mTexture = 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;
-        gl::MakeValidSize(false, gl::IsCompressed(internalformat), &size, &height, &mLodOffset);
-        HRESULT result = device->CreateCubeTexture(size, levels ? levels + mLodOffset : 0, getUsage(),
-                                                   mRenderer->ConvertTextureInternalFormat(internalformat), getPool(), &mTexture, NULL);
-
-        if (FAILED(result))
-        {
-            ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
-            error(GL_OUT_OF_MEMORY);
-        }
-    }
-
-    initializeRenderTarget();
+    TextureStorageCubeMap9 *newInterface = new TextureStorageCubeMap9(renderer, levels, internalformat, usage, forceRenderable, size); // D3D9_REPLACE
+    mInterface = newInterface;
 }
 
 TextureStorageCubeMap::~TextureStorageCubeMap()
 {
-    if (mTexture)
-    {
-        mTexture->Release();
-    }
-
-    for (int i = 0; i < 6; ++i)
-    {
-        delete mRenderTarget[i];
-    }
-}
-
-// Increments refcount on surface.
-// caller must Release() the returned surface
-IDirect3DSurface9 *TextureStorageCubeMap::getCubeMapSurface(GLenum faceTarget, int level, bool dirty)
-{
-    IDirect3DSurface9 *surface = NULL;
-
-    if (mTexture)
-    {
-        D3DCUBEMAP_FACES face = gl_d3d9::ConvertCubeFace(faceTarget);
-        HRESULT result = mTexture->GetCubeMapSurface(face, level + mLodOffset, &surface);
-        ASSERT(SUCCEEDED(result));
-
-        // With managed textures the driver needs to be informed of updates to the lower mipmap levels
-        if (level != 0 && isManaged() && dirty)
-        {
-            mTexture->AddDirtyRect(face, NULL);
-        }
-    }
-
-    return surface;
 }
 
 RenderTarget *TextureStorageCubeMap::getRenderTarget(GLenum faceTarget) const
 {
-    return mRenderTarget[gl::TextureCubeMap::faceIndex(faceTarget)];
+    return mInterface->getRenderTarget(faceTarget);
 }
 
 void TextureStorageCubeMap::generateMipmap(int face, int level)
 {
-    IDirect3DSurface9 *upper = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level - 1, false);
-    IDirect3DSurface9 *lower = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, true);
-
-    if (upper != NULL && lower != NULL)
-    {
-        mRenderer->boxFilter(upper, lower);
-    }
-
-    if (upper != NULL) upper->Release();
-    if (lower != NULL) lower->Release();
-}
-
-IDirect3DBaseTexture9 *TextureStorageCubeMap::getBaseTexture() const
-{
-    return mTexture;
+    mInterface->generateMipmap(face, level);
 }
 
 unsigned int TextureStorageCubeMap::getRenderTargetSerial(GLenum target) const
@@ -312,26 +124,4 @@
     return mFirstRenderTargetSerial + gl::TextureCubeMap::faceIndex(target);
 }
 
-void TextureStorageCubeMap::initializeRenderTarget()
-{
-    if (mTexture != NULL && isRenderTarget())
-    {
-        IDirect3DSurface9 *surface = NULL;
-
-        for (int i = 0; i < 6; ++i)
-        {
-            surface = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, false);
-
-            mRenderTarget[i] = new RenderTarget9(mRenderer, surface);
-        }
-    }
-    else
-    {
-        for (int i = 0; i < 6; ++i)
-        {
-            mRenderTarget[i] = NULL;
-        }
-    }
-}
-
 }
\ No newline at end of file
diff --git a/src/libGLESv2/renderer/TextureStorage.h b/src/libGLESv2/renderer/TextureStorage.h
index 7231c5f..c4c922a 100644
--- a/src/libGLESv2/renderer/TextureStorage.h
+++ b/src/libGLESv2/renderer/TextureStorage.h
@@ -6,10 +6,10 @@
 
 // TextureStorage.h: Defines the abstract rx::TextureStorage class and its concrete derived
 // classes TextureStorage2D and TextureStorageCubeMap, which act as the interface to the
-// D3D-side texture.
+// GPU-side texture.
 
-#ifndef LIBGLESV2_TEXTURESTORAGE_H_
-#define LIBGLESV2_TEXTURESTORAGE_H_
+#ifndef LIBGLESV2_RENDERER_TEXTURESTORAGE_H_
+#define LIBGLESV2_RENDERER_TEXTURESTORAGE_H_
 
 #define GL_APICALL
 #include <GLES2/gl2.h>
@@ -28,8 +28,18 @@
 class TextureStorageInterface
 {
   public:
-    TextureStorageInterface();
-    virtual ~TextureStorageInterface();
+    TextureStorageInterface() {};
+    virtual ~TextureStorageInterface() {};
+
+    virtual int getLodOffset() const = 0;
+    virtual bool isRenderTarget() const = 0;
+    virtual bool isManaged() const = 0;
+    virtual int levelCount() = 0;
+
+    virtual RenderTarget *getRenderTarget() const = 0;
+    virtual RenderTarget *getRenderTarget(GLenum faceTarget) const = 0;
+    virtual void generateMipmap(int level) = 0;
+    virtual void generateMipmap(int face, int level) = 0;
 
   private:
     DISALLOW_COPY_AND_ASSIGN(TextureStorageInterface);
@@ -39,36 +49,25 @@
 class TextureStorage
 {
   public:
-    TextureStorage(rx::Renderer *renderer, DWORD usage);
-
+    TextureStorage();
     virtual ~TextureStorage();
 
-    static DWORD GetTextureUsage(D3DFORMAT d3dfmt, GLenum glusage, bool forceRenderable);
-    static bool IsTextureFormatRenderable(D3DFORMAT format);
-
     TextureStorageInterface *getStorageInterface() { return mInterface; }
 
-    bool isRenderTarget() const;
-    bool isManaged() const;
-    D3DPOOL getPool() const;
-    DWORD getUsage() const;
     unsigned int getTextureSerial() const;
-    virtual IDirect3DBaseTexture9 *getBaseTexture() const = 0;
     virtual unsigned int getRenderTargetSerial(GLenum target) const = 0;
-    int getLodOffset() const;
-    int levelCount();
+
+    virtual int getLodOffset() const;
+    virtual bool isRenderTarget() const;
+    virtual bool isManaged() const;
+    virtual int levelCount();
 
   protected:
-    int mLodOffset;
-    rx::Renderer9 *mRenderer;
     TextureStorageInterface *mInterface;
 
   private:
     DISALLOW_COPY_AND_ASSIGN(TextureStorage);
 
-    const DWORD mD3DUsage;
-    const D3DPOOL mD3DPool;
-
     const unsigned int mTextureSerial;
     static unsigned int issueTextureSerial();
 
@@ -78,53 +77,39 @@
 class TextureStorage2D : public TextureStorage
 {
   public:
-    explicit TextureStorage2D(rx::Renderer *renderer, rx::SwapChain9 *swapchain);
-    TextureStorage2D(rx::Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height);
-
+    TextureStorage2D(Renderer *renderer, SwapChain9 *swapchain);
+    TextureStorage2D(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height);
     virtual ~TextureStorage2D();
 
-    IDirect3DSurface9 *getSurfaceLevel(int level, bool dirty);
-    RenderTarget *getRenderTarget() const;
-    virtual IDirect3DBaseTexture9 *getBaseTexture() const;
     void generateMipmap(int level);
+    RenderTarget *getRenderTarget() const;
 
     virtual unsigned int getRenderTargetSerial(GLenum target) const;
 
   private:
     DISALLOW_COPY_AND_ASSIGN(TextureStorage2D);
 
-    void initializeRenderTarget();
-
-    IDirect3DTexture9 *mTexture;
-    RenderTarget9 *mRenderTarget;
     const unsigned int mRenderTargetSerial;
 };
 
 class TextureStorageCubeMap : public TextureStorage
 {
   public:
-    TextureStorageCubeMap(rx::Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size);
-
+    TextureStorageCubeMap(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size);
     virtual ~TextureStorageCubeMap();
 
-    IDirect3DSurface9 *getCubeMapSurface(GLenum faceTarget, int level, bool dirty);
-    RenderTarget *getRenderTarget(GLenum faceTarget) const;
-    virtual IDirect3DBaseTexture9 *getBaseTexture() const;
     void generateMipmap(int face, int level);
+    RenderTarget *getRenderTarget(GLenum faceTarget) const;
 
     virtual unsigned int getRenderTargetSerial(GLenum target) const;
 
   private:
     DISALLOW_COPY_AND_ASSIGN(TextureStorageCubeMap);
 
-    void initializeRenderTarget();
-
-    IDirect3DCubeTexture9 *mTexture;
-    RenderTarget9 *mRenderTarget[6];
     const unsigned int mFirstRenderTargetSerial;
 };
 
 }
 
-#endif // LIBGLESV2_TEXTURESTORAGE_H_
+#endif // LIBGLESV2_RENDERER_TEXTURESTORAGE_H_
 
diff --git a/src/libGLESv2/renderer/TextureStorage9.cpp b/src/libGLESv2/renderer/TextureStorage9.cpp
new file mode 100644
index 0000000..6d84ff3
--- /dev/null
+++ b/src/libGLESv2/renderer/TextureStorage9.cpp
@@ -0,0 +1,328 @@
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// TextureStorage9.cpp: Implements the abstract rx::TextureStorage9 class and its concrete derived
+// classes TextureStorage2D9 and TextureStorageCubeMap9, which act as the interface to the
+// D3D9 texture.
+
+#include "libGLESv2/main.h"
+#include "libGLESv2/renderer/TextureStorage9.h"
+#include "libGLESv2/renderer/SwapChain9.h"
+#include "libGLESv2/renderer/Blit.h"
+#include "libGLESv2/renderer/RenderTarget9.h"
+#include "libGLESv2/renderer/renderer9_utils.h"
+
+#include "common/debug.h"
+
+namespace rx
+{
+TextureStorage9::TextureStorage9(Renderer *renderer, DWORD usage)
+    : mLodOffset(0),
+      mRenderer(Renderer9::makeRenderer9(renderer)),
+      mD3DUsage(usage),
+      mD3DPool(mRenderer->getTexturePool(usage))
+{
+}
+
+TextureStorage9::~TextureStorage9()
+{
+}
+
+TextureStorage9 *TextureStorage9::makeTextureStorage9(TextureStorageInterface *storage)
+{
+    ASSERT(dynamic_cast<TextureStorage9*>(storage) != NULL);
+    return static_cast<TextureStorage9*>(storage);
+}
+
+DWORD TextureStorage9::GetTextureUsage(D3DFORMAT d3dfmt, GLenum glusage, bool forceRenderable)
+{
+    DWORD d3dusage = 0;
+
+    if (d3dfmt == D3DFMT_INTZ)
+    {
+        d3dusage |= D3DUSAGE_DEPTHSTENCIL;
+    }
+    else if(forceRenderable || (TextureStorage9::IsTextureFormatRenderable(d3dfmt) && (glusage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE)))
+    {
+        d3dusage |= D3DUSAGE_RENDERTARGET;
+    }
+    return d3dusage;
+}
+
+bool TextureStorage9::IsTextureFormatRenderable(D3DFORMAT format)
+{
+    if (format == D3DFMT_INTZ)
+    {
+        return true;
+    }
+    switch(format)
+    {
+      case D3DFMT_L8:
+      case D3DFMT_A8L8:
+      case D3DFMT_DXT1:
+      case D3DFMT_DXT3:
+      case D3DFMT_DXT5:
+        return false;
+      case D3DFMT_A8R8G8B8:
+      case D3DFMT_X8R8G8B8:
+      case D3DFMT_A16B16G16R16F:
+      case D3DFMT_A32B32G32R32F:
+        return true;
+      default:
+        UNREACHABLE();
+    }
+
+    return false;
+}
+
+bool TextureStorage9::isRenderTarget() const
+{
+    return (mD3DUsage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL)) != 0;
+}
+
+bool TextureStorage9::isManaged() const
+{
+    return (mD3DPool == D3DPOOL_MANAGED);
+}
+
+D3DPOOL TextureStorage9::getPool() const
+{
+    return mD3DPool;
+}
+
+DWORD TextureStorage9::getUsage() const
+{
+    return mD3DUsage;
+}
+
+int TextureStorage9::getLodOffset() const
+{
+    return mLodOffset;
+}
+
+int TextureStorage9::levelCount()
+{
+    return getBaseTexture() ? getBaseTexture()->GetLevelCount() - getLodOffset() : 0;
+}
+
+TextureStorage2D9::TextureStorage2D9(Renderer *renderer, SwapChain9 *swapchain) : TextureStorage9(renderer, D3DUSAGE_RENDERTARGET)
+{
+    IDirect3DTexture9 *surfaceTexture = swapchain->getOffscreenTexture();
+    mTexture = surfaceTexture;
+
+    initializeRenderTarget();
+}
+
+TextureStorage2D9::TextureStorage2D9(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height)
+    : TextureStorage9(renderer, GetTextureUsage(Renderer9::makeRenderer9(renderer)->ConvertTextureInternalFormat(internalformat), usage, forceRenderable))
+{
+    mTexture = 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();
+        gl::MakeValidSize(false, gl::IsCompressed(internalformat), &width, &height, &mLodOffset);
+        HRESULT result = device->CreateTexture(width, height, levels ? levels + mLodOffset : 0, getUsage(),
+                                               mRenderer->ConvertTextureInternalFormat(internalformat), getPool(), &mTexture, NULL);
+
+        if (FAILED(result))
+        {
+            ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+            error(GL_OUT_OF_MEMORY);
+        }
+    }
+
+    initializeRenderTarget();
+}
+
+TextureStorage2D9::~TextureStorage2D9()
+{
+    if (mTexture)
+    {
+        mTexture->Release();
+    }
+
+    delete mRenderTarget;
+}
+
+TextureStorage2D9 *TextureStorage2D9::makeTextureStorage2D9(TextureStorageInterface *storage)
+{
+    ASSERT(dynamic_cast<TextureStorage2D9*>(storage) != NULL);
+    return static_cast<TextureStorage2D9*>(storage);
+}
+
+// Increments refcount on surface.
+// caller must Release() the returned surface
+IDirect3DSurface9 *TextureStorage2D9::getSurfaceLevel(int level, bool dirty)
+{
+    IDirect3DSurface9 *surface = NULL;
+
+    if (mTexture)
+    {
+        HRESULT result = mTexture->GetSurfaceLevel(level + mLodOffset, &surface);
+        ASSERT(SUCCEEDED(result));
+
+        // With managed textures the driver needs to be informed of updates to the lower mipmap levels
+        if (level != 0 && isManaged() && dirty)
+        {
+            mTexture->AddDirtyRect(NULL);
+        }
+    }
+
+    return surface;
+}
+
+RenderTarget *TextureStorage2D9::getRenderTarget() const
+{
+    return mRenderTarget;
+}
+
+void TextureStorage2D9::generateMipmap(int level)
+{
+    IDirect3DSurface9 *upper = getSurfaceLevel(level - 1, false);
+    IDirect3DSurface9 *lower = getSurfaceLevel(level, true);
+
+    if (upper != NULL && lower != NULL)
+    {
+        mRenderer->boxFilter(upper, lower);
+    }
+
+    if (upper != NULL) upper->Release();
+    if (lower != NULL) lower->Release();
+}
+
+IDirect3DBaseTexture9 *TextureStorage2D9::getBaseTexture() const
+{
+    return mTexture;
+}
+
+void TextureStorage2D9::initializeRenderTarget()
+{
+    if (mTexture != NULL && isRenderTarget())
+    {
+        IDirect3DSurface9 *surface = getSurfaceLevel(0, false);
+
+        mRenderTarget = new RenderTarget9(mRenderer, surface);
+    }
+    else
+    {
+        mRenderTarget = NULL;
+    }
+}
+
+TextureStorageCubeMap9::TextureStorageCubeMap9(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size)
+    : TextureStorage9(renderer, GetTextureUsage(Renderer9::makeRenderer9(renderer)->ConvertTextureInternalFormat(internalformat), usage, forceRenderable))
+{
+    mTexture = 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;
+        gl::MakeValidSize(false, gl::IsCompressed(internalformat), &size, &height, &mLodOffset);
+        HRESULT result = device->CreateCubeTexture(size, levels ? levels + mLodOffset : 0, getUsage(),
+                                                   mRenderer->ConvertTextureInternalFormat(internalformat), getPool(), &mTexture, NULL);
+
+        if (FAILED(result))
+        {
+            ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+            error(GL_OUT_OF_MEMORY);
+        }
+    }
+
+    initializeRenderTarget();
+}
+
+TextureStorageCubeMap9::~TextureStorageCubeMap9()
+{
+    if (mTexture)
+    {
+        mTexture->Release();
+    }
+
+    for (int i = 0; i < 6; ++i)
+    {
+        delete mRenderTarget[i];
+    }
+}
+
+TextureStorageCubeMap9 *TextureStorageCubeMap9::makeTextureStorageCubeMap9(TextureStorageInterface *storage)
+{
+    ASSERT(dynamic_cast<TextureStorageCubeMap9*>(storage) != NULL);
+    return static_cast<TextureStorageCubeMap9*>(storage);
+}
+
+// Increments refcount on surface.
+// caller must Release() the returned surface
+IDirect3DSurface9 *TextureStorageCubeMap9::getCubeMapSurface(GLenum faceTarget, int level, bool dirty)
+{
+    IDirect3DSurface9 *surface = NULL;
+
+    if (mTexture)
+    {
+        D3DCUBEMAP_FACES face = gl_d3d9::ConvertCubeFace(faceTarget);
+        HRESULT result = mTexture->GetCubeMapSurface(face, level + mLodOffset, &surface);
+        ASSERT(SUCCEEDED(result));
+
+        // With managed textures the driver needs to be informed of updates to the lower mipmap levels
+        if (level != 0 && isManaged() && dirty)
+        {
+            mTexture->AddDirtyRect(face, NULL);
+        }
+    }
+
+    return surface;
+}
+
+RenderTarget *TextureStorageCubeMap9::getRenderTarget(GLenum faceTarget) const
+{
+    return mRenderTarget[gl::TextureCubeMap::faceIndex(faceTarget)];
+}
+
+void TextureStorageCubeMap9::generateMipmap(int face, int level)
+{
+    IDirect3DSurface9 *upper = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level - 1, false);
+    IDirect3DSurface9 *lower = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, true);
+
+    if (upper != NULL && lower != NULL)
+    {
+        mRenderer->boxFilter(upper, lower);
+    }
+
+    if (upper != NULL) upper->Release();
+    if (lower != NULL) lower->Release();
+}
+
+IDirect3DBaseTexture9 *TextureStorageCubeMap9::getBaseTexture() const
+{
+    return mTexture;
+}
+
+void TextureStorageCubeMap9::initializeRenderTarget()
+{
+    if (mTexture != NULL && isRenderTarget())
+    {
+        IDirect3DSurface9 *surface = NULL;
+
+        for (int i = 0; i < 6; ++i)
+        {
+            surface = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, false);
+
+            mRenderTarget[i] = new RenderTarget9(mRenderer, surface);
+        }
+    }
+    else
+    {
+        for (int i = 0; i < 6; ++i)
+        {
+            mRenderTarget[i] = NULL;
+        }
+    }
+}
+
+}
\ No newline at end of file
diff --git a/src/libGLESv2/renderer/TextureStorage9.h b/src/libGLESv2/renderer/TextureStorage9.h
new file mode 100644
index 0000000..41ce1b8
--- /dev/null
+++ b/src/libGLESv2/renderer/TextureStorage9.h
@@ -0,0 +1,113 @@
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// TextureStorage9.h: Defines the abstract rx::TextureStorage9 class and its concrete derived
+// classes TextureStorage2D9 and TextureStorageCubeMap9, which act as the interface to the
+// D3D9 texture.
+
+#ifndef LIBGLESV2_RENDERER_TEXTURESTORAGE9_H_
+#define LIBGLESV2_RENDERER_TEXTURESTORAGE9_H_
+
+#define GL_APICALL
+#include <GLES2/gl2.h>
+#include <d3d9.h>
+
+#include "libGLESv2/renderer/TextureStorage.h"
+#include "common/debug.h"
+
+namespace rx
+{
+class Renderer9;
+class SwapChain9;
+class RenderTarget;
+class RenderTarget9;
+class Blit;
+
+class TextureStorage9 : public TextureStorageInterface
+{
+  public:
+    TextureStorage9(Renderer *renderer, DWORD usage);
+    virtual ~TextureStorage9();
+
+    static TextureStorage9 *makeTextureStorage9(TextureStorageInterface *storage);
+
+    static DWORD GetTextureUsage(D3DFORMAT d3dfmt, GLenum glusage, bool forceRenderable);
+    static bool IsTextureFormatRenderable(D3DFORMAT format);
+
+    D3DPOOL getPool() const;
+    DWORD getUsage() const;
+
+    virtual IDirect3DBaseTexture9 *getBaseTexture() const = 0;
+    virtual RenderTarget *getRenderTarget() const { return NULL; }
+    virtual RenderTarget *getRenderTarget(GLenum faceTarget) const { return NULL; }
+    virtual void generateMipmap(int level) {};
+    virtual void generateMipmap(int face, int level) {};
+
+    virtual int getLodOffset() const;
+    virtual bool isRenderTarget() const;
+    virtual bool isManaged() const;
+    virtual int levelCount();
+
+  protected:
+    int mLodOffset;
+    Renderer9 *mRenderer;
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(TextureStorage9);
+
+    const DWORD mD3DUsage;
+    const D3DPOOL mD3DPool;
+};
+
+class TextureStorage2D9 : public TextureStorage9
+{
+  public:
+    TextureStorage2D9(Renderer *renderer, SwapChain9 *swapchain);
+    TextureStorage2D9(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height);
+    virtual ~TextureStorage2D9();
+
+    static TextureStorage2D9 *makeTextureStorage2D9(TextureStorageInterface *storage);
+
+    IDirect3DSurface9 *getSurfaceLevel(int level, bool dirty);
+    virtual RenderTarget *getRenderTarget() const;
+    virtual IDirect3DBaseTexture9 *getBaseTexture() const;
+    virtual void generateMipmap(int level);
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(TextureStorage2D9);
+
+    void initializeRenderTarget();
+
+    IDirect3DTexture9 *mTexture;
+    RenderTarget9 *mRenderTarget;
+};
+
+class TextureStorageCubeMap9 : public TextureStorage9
+{
+  public:
+    TextureStorageCubeMap9(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size);
+    virtual ~TextureStorageCubeMap9();
+
+    static TextureStorageCubeMap9 *makeTextureStorageCubeMap9(TextureStorageInterface *storage);
+
+    IDirect3DSurface9 *getCubeMapSurface(GLenum faceTarget, int level, bool dirty);
+    virtual RenderTarget *getRenderTarget(GLenum faceTarget) const;
+    virtual IDirect3DBaseTexture9 *getBaseTexture() const;
+    virtual void generateMipmap(int face, int level);
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(TextureStorageCubeMap9);
+
+    void initializeRenderTarget();
+
+    IDirect3DCubeTexture9 *mTexture;
+    RenderTarget9 *mRenderTarget[6];
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_TEXTURESTORAGE9_H_
+