RenderTarget11 now stores a Resource instead of a Texture2D.

TRAC #22705

Signed-off-by: Jamie Madill
Signed-off-by: Shannon Woods
Author: Geoff Lang

git-svn-id: https://angleproject.googlecode.com/svn/branches/es3proto@2163 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/renderer/RenderTarget11.cpp b/src/libGLESv2/renderer/RenderTarget11.cpp
index cf226de..29d894a 100644
--- a/src/libGLESv2/renderer/RenderTarget11.cpp
+++ b/src/libGLESv2/renderer/RenderTarget11.cpp
@@ -17,17 +17,57 @@
 namespace rx
 {
 
-static unsigned int getRTVSubresourceIndex(ID3D11Texture2D *texture, ID3D11RenderTargetView *view)
+static bool getTextureProperties(ID3D11Resource *resource, unsigned int *mipLevels, unsigned int *samples)
+{
+    ID3D11Texture1D *texture1D = d3d11::DynamicCastComObject<ID3D11Texture1D>(resource);
+    if (texture1D)
+    {
+        D3D11_TEXTURE1D_DESC texDesc;
+        texture1D->GetDesc(&texDesc);
+        texture1D->Release();
+
+        *mipLevels = texDesc.MipLevels;
+        *samples = 0;
+
+        return true;
+    }
+
+    ID3D11Texture2D *texture2D = d3d11::DynamicCastComObject<ID3D11Texture2D>(resource);
+    if (texture2D)
+    {
+        D3D11_TEXTURE2D_DESC texDesc;
+        texture2D->GetDesc(&texDesc);
+        texture2D->Release();
+
+        *mipLevels = texDesc.MipLevels;
+        *samples = texDesc.SampleDesc.Count > 1 ? texDesc.SampleDesc.Count : 0;
+
+        return true;
+    }
+
+    ID3D11Texture3D *texture3D = d3d11::DynamicCastComObject<ID3D11Texture3D>(resource);
+    if (texture3D)
+    {
+        D3D11_TEXTURE3D_DESC texDesc;
+        texture3D->GetDesc(&texDesc);
+        texture3D->Release();
+
+        *mipLevels = texDesc.MipLevels;
+        *samples = 0;
+
+        return true;
+    }
+
+    return false;
+}
+
+static unsigned int getRTVSubresourceIndex(ID3D11Resource *resource, ID3D11RenderTargetView *view)
 {
     D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
     view->GetDesc(&rtvDesc);
 
-    D3D11_TEXTURE2D_DESC texDesc;
-    texture->GetDesc(&texDesc);
-
     unsigned int mipSlice = 0;
     unsigned int arraySlice = 0;
-    unsigned int mipLevels = texDesc.MipLevels;
 
     switch (rtvDesc.ViewDimension)
     {
@@ -76,20 +116,19 @@
         break;
     }
 
+    unsigned int mipLevels, samples;
+    getTextureProperties(resource,  &mipLevels, &samples);
+
     return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels);
 }
 
-static unsigned int getDSVSubresourceIndex(ID3D11Texture2D *texture, ID3D11DepthStencilView *view)
+static unsigned int getDSVSubresourceIndex(ID3D11Resource *resource, ID3D11DepthStencilView *view)
 {
     D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
     view->GetDesc(&dsvDesc);
 
-    D3D11_TEXTURE2D_DESC texDesc;
-    texture->GetDesc(&texDesc);
-
     unsigned int mipSlice = 0;
     unsigned int arraySlice = 0;
-    unsigned int mipLevels = texDesc.MipLevels;
 
     switch (dsvDesc.ViewDimension)
     {
@@ -123,7 +162,7 @@
         arraySlice = dsvDesc.Texture2DMSArray.FirstArraySlice;
         break;
 
-      case D3D11_RTV_DIMENSION_UNKNOWN:
+      case D3D11_DSV_DIMENSION_UNKNOWN:
         UNIMPLEMENTED();
         break;
 
@@ -132,13 +171,16 @@
         break;
     }
 
+    unsigned int mipLevels, samples;
+    getTextureProperties(resource, &mipLevels, &samples);
+
     return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels);
 }
 
-RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11RenderTargetView *rtv, ID3D11Texture2D *tex, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height)
+RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11RenderTargetView *rtv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height)
 {
     mRenderer = Renderer11::makeRenderer11(renderer);
-    mTexture = tex;
+    mTexture = resource;
     mRenderTarget = rtv;
     mDepthStencil = NULL;
     mShaderResource = srv;
@@ -149,23 +191,23 @@
         D3D11_RENDER_TARGET_VIEW_DESC desc;
         mRenderTarget->GetDesc(&desc);
 
-        D3D11_TEXTURE2D_DESC texDesc;
-        mTexture->GetDesc(&texDesc);
+        unsigned int mipLevels, samples;
+        getTextureProperties(mTexture, &mipLevels, &samples);
 
         mSubresourceIndex = getRTVSubresourceIndex(mTexture, mRenderTarget);
         mWidth = width;
         mHeight = height;
-        mSamples = (texDesc.SampleDesc.Count > 1) ? texDesc.SampleDesc.Count : 0;
+        mSamples = samples;
 
         mInternalFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format);
         mActualFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format);
     }
 }
 
-RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *dsv, ID3D11Texture2D *tex, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height)
+RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *dsv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height)
 {
     mRenderer = Renderer11::makeRenderer11(renderer);
-    mTexture = tex;
+    mTexture = resource;
     mRenderTarget = NULL;
     mDepthStencil = dsv;
     mShaderResource = srv;
@@ -176,13 +218,13 @@
         D3D11_DEPTH_STENCIL_VIEW_DESC desc;
         mDepthStencil->GetDesc(&desc);
 
-        D3D11_TEXTURE2D_DESC texDesc;
-        mTexture->GetDesc(&texDesc);
+        unsigned int mipLevels, samples;
+        getTextureProperties(mTexture, &mipLevels, &samples);
 
         mSubresourceIndex = getDSVSubresourceIndex(mTexture, mDepthStencil);
         mWidth = width;
         mHeight = height;
-        mSamples = (texDesc.SampleDesc.Count > 1) ? texDesc.SampleDesc.Count : 0;
+        mSamples = samples;
 
         mInternalFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format);
         mActualFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format);
@@ -223,7 +265,9 @@
         desc.BindFlags = (depth ? D3D11_BIND_DEPTH_STENCIL : (D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE));
 
         ID3D11Device *device = mRenderer->getDevice();
-        HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
+        ID3D11Texture2D *texture = NULL;
+        HRESULT result = device->CreateTexture2D(&desc, NULL, &texture);
+        mTexture = texture;
 
         if (result == E_OUTOFMEMORY)
         {
@@ -327,7 +371,7 @@
     return static_cast<rx::RenderTarget11*>(target);
 }
 
-ID3D11Texture2D *RenderTarget11::getTexture() const
+ID3D11Resource *RenderTarget11::getTexture() const
 {
     if (mTexture)
     {
diff --git a/src/libGLESv2/renderer/RenderTarget11.h b/src/libGLESv2/renderer/RenderTarget11.h
index dc697cf..01d3537 100644
--- a/src/libGLESv2/renderer/RenderTarget11.h
+++ b/src/libGLESv2/renderer/RenderTarget11.h
@@ -20,15 +20,15 @@
 class RenderTarget11 : public RenderTarget
 {
   public:
-    RenderTarget11(Renderer *renderer, ID3D11RenderTargetView *rtv, ID3D11Texture2D *tex, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height);
-    RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *dsv, ID3D11Texture2D *tex, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height);
+    RenderTarget11(Renderer *renderer, ID3D11RenderTargetView *rtv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height);
+    RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *dsv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height);
     RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height, GLenum format, GLsizei samples, bool depth);
     virtual ~RenderTarget11();
 
     static RenderTarget11 *makeRenderTarget11(RenderTarget *renderTarget);
 
     // Adds reference, caller must call Release
-    ID3D11Texture2D *getTexture() const;
+    ID3D11Resource *getTexture() const;
 
     // Adds reference, caller must call Release
     ID3D11RenderTargetView *getRenderTargetView() const;
@@ -45,7 +45,7 @@
     DISALLOW_COPY_AND_ASSIGN(RenderTarget11);
 
     unsigned int mSubresourceIndex;
-    ID3D11Texture2D *mTexture;
+    ID3D11Resource *mTexture;
     ID3D11RenderTargetView *mRenderTarget;
     ID3D11DepthStencilView *mDepthStencil;
     ID3D11ShaderResourceView *mShaderResource;
@@ -55,4 +55,4 @@
 
 }
 
-#endif LIBGLESV2_RENDERER_RENDERTARGET11_H_
\ No newline at end of file
+#endif LIBGLESV2_RENDERER_RENDERTARGET11_H_
diff --git a/src/libGLESv2/renderer/Renderer11.cpp b/src/libGLESv2/renderer/Renderer11.cpp
index c0cc532..f86912b 100644
--- a/src/libGLESv2/renderer/Renderer11.cpp
+++ b/src/libGLESv2/renderer/Renderer11.cpp
@@ -3503,16 +3503,21 @@
         return gl::error(GL_OUT_OF_MEMORY, false);
     }
 
-    ID3D11Texture2D *readTexture = NULL;
+    ID3D11Resource *readTexture = NULL;
     unsigned int readSubresource = 0;
     if (readRenderTarget->getSamples() > 0)
     {
-        ID3D11Texture2D *unresolvedTexture = readRenderTarget11->getTexture();
+        ID3D11Resource *unresolvedResource = readRenderTarget11->getTexture();
+        ID3D11Texture2D *unresolvedTexture = d3d11::DynamicCastComObject<ID3D11Texture2D>(unresolvedResource);
+        unresolvedResource->Release();
 
-        readTexture = resolveMultisampledTexture(unresolvedTexture, readRenderTarget11->getSubresourceIndex());
-        readSubresource = 0;
+        if (unresolvedTexture)
+        {
+            readTexture = resolveMultisampledTexture(unresolvedTexture, readRenderTarget11->getSubresourceIndex());
+            readSubresource = 0;
 
-        unresolvedTexture->Release();
+            unresolvedTexture->Release();
+        }
     }
     else
     {
@@ -3534,7 +3539,7 @@
         return gl::error(GL_OUT_OF_MEMORY, false);
     }
 
-    ID3D11Texture2D *drawTexture = drawRenderTarget11->getTexture();
+    ID3D11Resource *drawTexture = drawRenderTarget11->getTexture();
     unsigned int drawSubresource = drawRenderTarget11->getSubresourceIndex();
 
     D3D11_BOX readBox;
diff --git a/src/libGLESv2/renderer/renderer11_utils.h b/src/libGLESv2/renderer/renderer11_utils.h
index 1bc48c1..48ed871 100644
--- a/src/libGLESv2/renderer/renderer11_utils.h
+++ b/src/libGLESv2/renderer/renderer11_utils.h
@@ -75,6 +75,25 @@
 
 HRESULT SetDebugName(ID3D11DeviceChild *resource, const char *name);
 
+template <typename outType>
+outType* DynamicCastComObject(IUnknown* object)
+{
+    outType *outObject = NULL;
+    HRESULT result = object->QueryInterface(__uuidof(outType), reinterpret_cast<void**>(&outObject));
+    if (SUCCEEDED(result))
+    {
+        return outObject;
+    }
+    else
+    {
+        if (outObject)
+        {
+            outObject->Release();
+        }
+        return NULL;
+    }
+}
+
 inline bool isDeviceLostError(HRESULT errorCode)
 {
     switch (errorCode)