Update the getRenderTarget functions to return gl::Error objects.

BUG=angle:520

Change-Id: If1f4f71972b669704eff70b5f60927d8e6ac07b3
Reviewed-on: https://chromium-review.googlesource.com/218767
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Tested-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp
index 752212a..457befb 100644
--- a/src/libGLESv2/Context.cpp
+++ b/src/libGLESv2/Context.cpp
@@ -1616,7 +1616,11 @@
 
     ClearParameters clearParams = mState.getClearParameters(mask);
 
-    applyRenderTarget(GL_TRIANGLES, true);   // Clips the clear to the scissor rectangle but not the viewport
+    Error error = applyRenderTarget(GL_TRIANGLES, true);   // Clips the clear to the scissor rectangle but not the viewport
+    if (error.isError())
+    {
+        return error;
+    }
 
     return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
 }
@@ -1647,7 +1651,11 @@
         clearParams.depthClearValue = values[0];
     }
 
-    applyRenderTarget(GL_TRIANGLES, true);   // Clips the clear to the scissor rectangle but not the viewport
+    Error error = applyRenderTarget(GL_TRIANGLES, true);   // Clips the clear to the scissor rectangle but not the viewport
+    if (error.isError())
+    {
+        return error;
+    }
 
     return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
 }
@@ -1668,7 +1676,11 @@
     clearParams.colorUIClearValue = ColorUI(values[0], values[1], values[2], values[3]);
     clearParams.colorClearType = GL_UNSIGNED_INT;
 
-    applyRenderTarget(GL_TRIANGLES, true);   // Clips the clear to the scissor rectangle but not the viewport
+    Error error = applyRenderTarget(GL_TRIANGLES, true);   // Clips the clear to the scissor rectangle but not the viewport
+    if (error.isError())
+    {
+        return error;
+    }
 
     return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
 }
@@ -1699,7 +1711,11 @@
         clearParams.stencilClearValue = values[1];
     }
 
-    applyRenderTarget(GL_TRIANGLES, true);   // Clips the clear to the scissor rectangle but not the viewport
+    Error error = applyRenderTarget(GL_TRIANGLES, true);   // Clips the clear to the scissor rectangle but not the viewport
+    if (error.isError())
+    {
+        return error;
+    }
 
     return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
 }
@@ -1718,7 +1734,11 @@
     clearParams.clearStencil = true;
     clearParams.stencilClearValue = stencil;
 
-    applyRenderTarget(GL_TRIANGLES, true);   // Clips the clear to the scissor rectangle but not the viewport
+    Error error = applyRenderTarget(GL_TRIANGLES, true);   // Clips the clear to the scissor rectangle but not the viewport
+    if (error.isError())
+    {
+        return error;
+    }
 
     return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
 }
diff --git a/src/libGLESv2/Framebuffer.cpp b/src/libGLESv2/Framebuffer.cpp
index 5f9d244..9cd9e25 100644
--- a/src/libGLESv2/Framebuffer.cpp
+++ b/src/libGLESv2/Framebuffer.cpp
@@ -23,7 +23,7 @@
 
 namespace rx
 {
-RenderTarget *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment)
+gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget **outRT)
 {
     if (attachment->isTexture())
     {
@@ -32,14 +32,17 @@
         TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation());
         const gl::ImageIndex *index = attachment->getTextureImageIndex();
         ASSERT(index);
-        return textureD3D->getRenderTarget(*index);
+        return textureD3D->getRenderTarget(*index, outRT);
     }
+    else
+    {
+        gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer();
+        ASSERT(renderbuffer);
 
-    gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer();
-    ASSERT(renderbuffer);
-
-    // TODO: cast to RenderbufferD3D
-    return renderbuffer->getStorage()->getRenderTarget();
+        // TODO: cast to RenderbufferD3D
+        *outRT = renderbuffer->getStorage()->getRenderTarget();
+        return gl::Error(GL_NO_ERROR);
+    }
 }
 
 // Note: RenderTarget serials should ideally be in the RenderTargets themselves.
@@ -603,33 +606,36 @@
     return GL_FRAMEBUFFER_COMPLETE;
 }
 
-void Framebuffer::invalidate(const Caps &caps, GLsizei numAttachments, const GLenum *attachments)
+Error Framebuffer::invalidate(const Caps &caps, GLsizei numAttachments, const GLenum *attachments)
 {
     GLuint maxDimension = caps.maxRenderbufferSize;
-    invalidateSub(caps, numAttachments, attachments, 0, 0, maxDimension, maxDimension);
+    return invalidateSub(numAttachments, attachments, 0, 0, maxDimension, maxDimension);
 }
 
-void Framebuffer::invalidateSub(const Caps &caps, GLsizei numAttachments, const GLenum *attachments,
-                                GLint x, GLint y, GLsizei width, GLsizei height)
+Error Framebuffer::invalidateSub(GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height)
 {
     ASSERT(completeness() == GL_FRAMEBUFFER_COMPLETE);
     for (GLsizei attachIndex = 0; attachIndex < numAttachments; ++attachIndex)
     {
         GLenum attachmentTarget = attachments[attachIndex];
 
-        gl::FramebufferAttachment *attachment =
-            (attachmentTarget == GL_DEPTH_STENCIL_ATTACHMENT) ? getDepthOrStencilbuffer() :
-                                                                getAttachment(attachmentTarget);
+        FramebufferAttachment *attachment = (attachmentTarget == GL_DEPTH_STENCIL_ATTACHMENT) ? getDepthOrStencilbuffer()
+                                                                                              : getAttachment(attachmentTarget);
 
         if (attachment)
         {
-            rx::RenderTarget *renderTarget = rx::GetAttachmentRenderTarget(attachment);
-            if (renderTarget)
+            rx::RenderTarget *renderTarget = NULL;
+            Error error = rx::GetAttachmentRenderTarget(attachment, &renderTarget);
+            if (error.isError())
             {
-                renderTarget->invalidate(x, y, width, height);
+                return error;
             }
+
+            renderTarget->invalidate(x, y, width, height);
         }
     }
+
+    return Error(GL_NO_ERROR);
 }
 
 DefaultFramebuffer::DefaultFramebuffer(rx::Renderer *renderer, Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil)
diff --git a/src/libGLESv2/Framebuffer.h b/src/libGLESv2/Framebuffer.h
index 355402c..1f55b43 100644
--- a/src/libGLESv2/Framebuffer.h
+++ b/src/libGLESv2/Framebuffer.h
@@ -10,12 +10,14 @@
 #ifndef LIBGLESV2_FRAMEBUFFER_H_
 #define LIBGLESV2_FRAMEBUFFER_H_
 
-#include <vector>
+#include "libGLESv2/Error.h"
 
 #include "common/angleutils.h"
 #include "common/RefCountObject.h"
 #include "Constants.h"
 
+#include <vector>
+
 namespace rx
 {
 class Renderer;
@@ -72,9 +74,8 @@
     virtual GLenum completeness() const;
     bool hasValidDepthStencil() const;
 
-    void invalidate(const Caps &caps, GLsizei numAttachments, const GLenum *attachments);
-    void invalidateSub(const Caps &caps, GLsizei numAttachments, const GLenum *attachments,
-                       GLint x, GLint y, GLsizei width, GLsizei height);
+    Error invalidate(const Caps &caps, GLsizei numAttachments, const GLenum *attachments);
+    Error invalidateSub(GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height);
 
     // Use this method to retrieve the color buffer map when doing rendering.
     // It will apply a workaround for poor shader performance on some systems
@@ -118,7 +119,7 @@
 class RenderTarget;
 
 // TODO: place this in FramebufferD3D.h
-RenderTarget *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment);
+gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget **outRT);
 unsigned int GetAttachmentSerial(gl::FramebufferAttachment *attachment);
 
 }
diff --git a/src/libGLESv2/libGLESv2.cpp b/src/libGLESv2/libGLESv2.cpp
index 4f43af5..bd7774a 100644
--- a/src/libGLESv2/libGLESv2.cpp
+++ b/src/libGLESv2/libGLESv2.cpp
@@ -8283,7 +8283,12 @@
         gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
         if (framebuffer && framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE)
         {
-            framebuffer->invalidate(context->getCaps(), numAttachments, attachments);
+            gl::Error error = framebuffer->invalidate(context->getCaps(), numAttachments, attachments);
+            if (error.isError())
+            {
+                context->recordError(error);
+                return;
+            }
         }
     }
 }
@@ -8311,7 +8316,12 @@
         gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
         if (framebuffer && framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE)
         {
-            framebuffer->invalidateSub(context->getCaps(), numAttachments, attachments, x, y, width, height);
+            gl::Error error = framebuffer->invalidateSub(numAttachments, attachments, x, y, width, height);
+            if (error.isError())
+            {
+                context->recordError(error);
+                return;
+            }
         }
     }
 }
diff --git a/src/libGLESv2/renderer/Image.cpp b/src/libGLESv2/renderer/Image.cpp
index d4d6085..5b9b75f 100644
--- a/src/libGLESv2/renderer/Image.cpp
+++ b/src/libGLESv2/renderer/Image.cpp
@@ -32,7 +32,13 @@
     gl::FramebufferAttachment *colorbuffer = source->getReadColorbuffer();
     ASSERT(colorbuffer);
 
-    RenderTarget *renderTarget = GetAttachmentRenderTarget(colorbuffer);
+    RenderTarget *renderTarget = NULL;
+    gl::Error error = GetAttachmentRenderTarget(colorbuffer, &renderTarget);
+    if (error.isError())
+    {
+        return error;
+    }
+
     ASSERT(renderTarget);
     return copy(xoffset, yoffset, zoffset, area, renderTarget);
 }
diff --git a/src/libGLESv2/renderer/d3d/TextureD3D.cpp b/src/libGLESv2/renderer/d3d/TextureD3D.cpp
index b4fd5a7..ea27c08 100644
--- a/src/libGLESv2/renderer/d3d/TextureD3D.cpp
+++ b/src/libGLESv2/renderer/d3d/TextureD3D.cpp
@@ -528,22 +528,25 @@
     if (isFastUnpackable(unpack, sizedInternalFormat) && isLevelComplete(level))
     {
         // Will try to create RT storage if it does not exist
-        RenderTarget *destRenderTarget = getRenderTarget(index);
+        RenderTarget *destRenderTarget = NULL;
+        gl::Error error = getRenderTarget(index, &destRenderTarget);
+        if (error.isError())
+        {
+            return error;
+        }
+
         gl::Box destArea(0, 0, 0, getWidth(level), getHeight(level), 1);
 
-        if (destRenderTarget)
+        error = fastUnpackPixels(unpack, pixels, destArea, sizedInternalFormat, type, destRenderTarget);
+        if (error.isError())
         {
-            gl::Error error = fastUnpackPixels(unpack, pixels, destArea, sizedInternalFormat, type, destRenderTarget);
-            if (error.isError())
-            {
-                return error;
-            }
-
-            // Ensure we don't overwrite our newly initialized data
-            mImageArray[level]->markClean();
-
-            fastUnpacked = true;
+            return error;
         }
+
+        // Ensure we don't overwrite our newly initialized data
+        mImageArray[level]->markClean();
+
+        fastUnpacked = true;
     }
 
     if (!fastUnpacked)
@@ -582,21 +585,23 @@
     gl::Box destArea(xoffset, yoffset, 0, width, height, 1);
     if (isFastUnpackable(unpack, getInternalFormat(level)) && isLevelComplete(level))
     {
-        RenderTarget *renderTarget = getRenderTarget(index);
-
-        if (renderTarget)
+        RenderTarget *renderTarget = NULL;
+        gl::Error error = getRenderTarget(index, &renderTarget);
+        if (error.isError())
         {
-            gl::Error error = fastUnpackPixels(unpack, pixels, destArea, getInternalFormat(level), type, renderTarget);
-            if (error.isError())
-            {
-                return error;
-            }
-
-            // Ensure we don't overwrite our newly initialized data
-            mImageArray[level]->markClean();
-
-            fastUnpacked = true;
+            return error;
         }
+
+        error = fastUnpackPixels(unpack, pixels, destArea, getInternalFormat(level), type, renderTarget);
+        if (error.isError())
+        {
+            return error;
+        }
+
+        // Ensure we don't overwrite our newly initialized data
+        mImageArray[level]->markClean();
+
+        fastUnpacked = true;
     }
 
     if (!fastUnpacked)
@@ -797,7 +802,7 @@
     return (!ensureRenderTarget().isError() ? mTexStorage->getRenderTargetSerial(index) : 0);
 }
 
-RenderTarget *TextureD3D_2D::getRenderTarget(const gl::ImageIndex &index)
+gl::Error TextureD3D_2D::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
 {
     ASSERT(!index.hasLayer());
 
@@ -805,16 +810,16 @@
     gl::Error error = ensureRenderTarget();
     if (error.isError())
     {
-        return NULL;
+        return error;
     }
 
     error = updateStorageLevel(index.mipIndex);
     if (error.isError())
     {
-        return NULL;
+        return error;
     }
 
-    return mTexStorage->getRenderTarget(index);
+    return mTexStorage->getRenderTarget(index, outRT);
 }
 
 bool TextureD3D_2D::isValidLevel(int level) const
@@ -1352,7 +1357,7 @@
     return (ensureRenderTarget().isError() ? mTexStorage->getRenderTargetSerial(index) : 0);
 }
 
-RenderTarget *TextureD3D_Cube::getRenderTarget(const gl::ImageIndex &index)
+gl::Error TextureD3D_Cube::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
 {
     ASSERT(gl::IsCubemapTextureTarget(index.type));
 
@@ -1360,16 +1365,16 @@
     gl::Error error = ensureRenderTarget();
     if (error.isError())
     {
-        return NULL;
+        return error;
     }
 
     error = updateStorageFaceLevel(index.layerIndex, index.mipIndex);
     if (error.isError())
     {
-        return NULL;
+        return error;
     }
 
-    return mTexStorage->getRenderTarget(index);
+    return mTexStorage->getRenderTarget(index, outRT);
 }
 
 gl::Error TextureD3D_Cube::initializeStorage(bool renderTarget)
@@ -1703,22 +1708,25 @@
     if (isFastUnpackable(unpack, sizedInternalFormat))
     {
         // Will try to create RT storage if it does not exist
-        RenderTarget *destRenderTarget = getRenderTarget(index);
+        RenderTarget *destRenderTarget = NULL;
+        gl::Error error = getRenderTarget(index, &destRenderTarget);
+        if (error.isError())
+        {
+            return error;
+        }
+
         gl::Box destArea(0, 0, 0, getWidth(level), getHeight(level), getDepth(level));
 
-        if (destRenderTarget)
+        error = fastUnpackPixels(unpack, pixels, destArea, sizedInternalFormat, type, destRenderTarget);
+        if (error.isError())
         {
-            gl::Error error = fastUnpackPixels(unpack, pixels, destArea, sizedInternalFormat, type, destRenderTarget);
-            if (error.isError())
-            {
-                return error;
-            }
-
-            // Ensure we don't overwrite our newly initialized data
-            mImageArray[level]->markClean();
-
-            fastUnpacked = true;
+            return error;
         }
+
+        // Ensure we don't overwrite our newly initialized data
+        mImageArray[level]->markClean();
+
+        fastUnpacked = true;
     }
 
     if (!fastUnpacked)
@@ -1758,22 +1766,24 @@
     // Attempt a fast gpu copy of the pixel data to the surface if the app bound an unpack buffer
     if (isFastUnpackable(unpack, getInternalFormat(level)))
     {
-        RenderTarget *destRenderTarget = getRenderTarget(index);
-
-        if (destRenderTarget)
+        RenderTarget *destRenderTarget = NULL;
+        gl::Error error = getRenderTarget(index, &destRenderTarget);
+        if (error.isError())
         {
-            gl::Box destArea(xoffset, yoffset, zoffset, width, height, depth);
-            gl::Error error = fastUnpackPixels(unpack, pixels, destArea, getInternalFormat(level), type, destRenderTarget);
-            if (error.isError())
-            {
-                return error;
-            }
-
-            // Ensure we don't overwrite our newly initialized data
-            mImageArray[level]->markClean();
-
-            fastUnpacked = true;
+            return error;
         }
+
+        gl::Box destArea(xoffset, yoffset, zoffset, width, height, depth);
+        error = fastUnpackPixels(unpack, pixels, destArea, getInternalFormat(level), type, destRenderTarget);
+        if (error.isError())
+        {
+            return error;
+        }
+
+        // Ensure we don't overwrite our newly initialized data
+        mImageArray[level]->markClean();
+
+        fastUnpacked = true;
     }
 
     if (!fastUnpacked)
@@ -1922,13 +1932,13 @@
     return (!ensureRenderTarget().isError() ? mTexStorage->getRenderTargetSerial(index) : 0);
 }
 
-RenderTarget *TextureD3D_3D::getRenderTarget(const gl::ImageIndex &index)
+gl::Error TextureD3D_3D::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
 {
     // ensure the underlying texture is created
     gl::Error error = ensureRenderTarget();
     if (error.isError())
     {
-        return NULL;
+        return error;
     }
 
     if (index.hasLayer())
@@ -1936,7 +1946,7 @@
         error = updateStorage();
         if (error.isError())
         {
-            return NULL;
+            return error;
         }
     }
     else
@@ -1944,11 +1954,11 @@
         error = updateStorageLevel(index.mipIndex);
         if (error.isError())
         {
-            return NULL;
+            return error;
         }
     }
 
-    return mTexStorage->getRenderTarget(index);
+    return mTexStorage->getRenderTarget(index, outRT);
 }
 
 gl::Error TextureD3D_3D::initializeStorage(bool renderTarget)
@@ -2474,22 +2484,22 @@
     return (!ensureRenderTarget().isError() ? mTexStorage->getRenderTargetSerial(index) : 0);
 }
 
-RenderTarget *TextureD3D_2DArray::getRenderTarget(const gl::ImageIndex &index)
+gl::Error TextureD3D_2DArray::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
 {
     // ensure the underlying texture is created
     gl::Error error = ensureRenderTarget();
     if (error.isError())
     {
-        return NULL;
+        return error;
     }
 
     error = updateStorageLevel(index.mipIndex);
     if (error.isError())
     {
-        return NULL;
+        return error;
     }
 
-    return mTexStorage->getRenderTarget(index);
+    return mTexStorage->getRenderTarget(index, outRT);
 }
 
 gl::Error TextureD3D_2DArray::initializeStorage(bool renderTarget)
diff --git a/src/libGLESv2/renderer/d3d/TextureD3D.h b/src/libGLESv2/renderer/d3d/TextureD3D.h
index 94eb5c2..92ec478 100644
--- a/src/libGLESv2/renderer/d3d/TextureD3D.h
+++ b/src/libGLESv2/renderer/d3d/TextureD3D.h
@@ -48,7 +48,7 @@
 
     bool isImmutable() const { return mImmutable; }
 
-    virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index) = 0;
+    virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) = 0;
     virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index) = 0;
 
     // Returns an iterator over all "Images" for this particular Texture.
@@ -130,7 +130,7 @@
     virtual void bindTexImage(egl::Surface *surface);
     virtual void releaseTexImage();
 
-    virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
+    virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
     virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index);
 
     virtual gl::ImageIndexIterator imageIterator() const;
@@ -185,7 +185,7 @@
     virtual void bindTexImage(egl::Surface *surface);
     virtual void releaseTexImage();
 
-    virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
+    virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
     virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index);
 
     virtual gl::ImageIndexIterator imageIterator() const;
@@ -239,7 +239,7 @@
     virtual void bindTexImage(egl::Surface *surface);
     virtual void releaseTexImage();
 
-    virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
+    virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
     virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index);
 
     virtual gl::ImageIndexIterator imageIterator() const;
@@ -291,7 +291,7 @@
     virtual void bindTexImage(egl::Surface *surface);
     virtual void releaseTexImage();
 
-    virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
+    virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
     virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index);
 
     virtual gl::ImageIndexIterator imageIterator() const;
diff --git a/src/libGLESv2/renderer/d3d/TextureStorage.h b/src/libGLESv2/renderer/d3d/TextureStorage.h
index 6e9f6e4..0943d5f 100644
--- a/src/libGLESv2/renderer/d3d/TextureStorage.h
+++ b/src/libGLESv2/renderer/d3d/TextureStorage.h
@@ -9,6 +9,8 @@
 #ifndef LIBGLESV2_RENDERER_TEXTURESTORAGE_H_
 #define LIBGLESV2_RENDERER_TEXTURESTORAGE_H_
 
+#include "libGLESv2/Error.h"
+
 #include "common/debug.h"
 #include "libGLESv2/Error.h"
 
@@ -40,7 +42,7 @@
     virtual bool isManaged() const = 0;
     virtual int getLevelCount() const = 0;
 
-    virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index) = 0;
+    virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) = 0;
     virtual void generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex) = 0;
 
     virtual gl::Error copyToStorage(TextureStorage *destStorage) = 0;
diff --git a/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp b/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp
index c60b7a6..84698d0 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp
@@ -211,10 +211,11 @@
             gl::FramebufferAttachment *attachment = frameBuffer->getColorbuffer(colorAttachment);
             if (attachment)
             {
-                RenderTarget11 *renderTarget = d3d11::GetAttachmentRenderTarget(attachment);
-                if (!renderTarget)
+                RenderTarget11 *renderTarget = NULL;
+                gl::Error error = d3d11::GetAttachmentRenderTarget(attachment, &renderTarget);
+                if (error.isError())
                 {
-                    return gl::Error(GL_OUT_OF_MEMORY, "Internal render target view pointer unexpectedly null.");
+                    return error;
                 }
 
                 const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(attachment->getInternalFormat());
@@ -284,10 +285,11 @@
         gl::FramebufferAttachment *attachment = frameBuffer->getDepthOrStencilbuffer();
         if (attachment)
         {
-            RenderTarget11 *renderTarget = d3d11::GetAttachmentRenderTarget(attachment);
-            if (!renderTarget)
+            RenderTarget11 *renderTarget = NULL;
+            gl::Error error = d3d11::GetAttachmentRenderTarget(attachment, &renderTarget);
+            if (error.isError())
             {
-                return gl::Error(GL_OUT_OF_MEMORY, "Internal depth stencil view pointer unexpectedly null.");
+                return error;
             }
 
             const gl::InternalFormat &actualFormatInfo = gl::GetInternalFormatInfo(attachment->getActualFormat());
diff --git a/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
index 24ae9b1..5f54f09 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
@@ -884,17 +884,16 @@
             renderTargetSerials[colorAttachment] = GetAttachmentSerial(colorbuffer);
 
             // Extract the render target dimensions and view
-            RenderTarget11 *renderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer);
-            if (!renderTarget)
+            RenderTarget11 *renderTarget = NULL;
+            gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &renderTarget);
+            if (error.isError())
             {
-                return gl::Error(GL_OUT_OF_MEMORY, "Internal render target pointer unexpectedly null.");
+                return error;
             }
+            ASSERT(renderTarget);
 
             framebufferRTVs[colorAttachment] = renderTarget->getRenderTargetView();
-            if (!framebufferRTVs[colorAttachment])
-            {
-                return gl::Error(GL_OUT_OF_MEMORY, "Internal render target view pointer unexpectedly null.");
-            }
+            ASSERT(framebufferRTVs[colorAttachment]);
 
             if (missingColorRenderTarget)
             {
@@ -939,19 +938,17 @@
     ID3D11DepthStencilView* framebufferDSV = NULL;
     if (depthStencil)
     {
-        RenderTarget11 *depthStencilRenderTarget = d3d11::GetAttachmentRenderTarget(depthStencil);
-        if (!depthStencilRenderTarget)
+        RenderTarget11 *depthStencilRenderTarget = NULL;
+        gl::Error error = d3d11::GetAttachmentRenderTarget(depthStencil, &depthStencilRenderTarget);
+        if (error.isError())
         {
             SafeRelease(framebufferRTVs);
-            return gl::Error(GL_OUT_OF_MEMORY, "Internal render target pointer unexpectedly null.");
+            return error;
         }
+        ASSERT(depthStencilRenderTarget);
 
         framebufferDSV = depthStencilRenderTarget->getDepthStencilView();
-        if (!framebufferDSV)
-        {
-            SafeRelease(framebufferRTVs);
-            return gl::Error(GL_OUT_OF_MEMORY, "Internal depth stencil view pointer unexpectedly null.");
-        }
+        ASSERT(framebufferDSV);
 
         // If there is no render buffer, the width, height and format values come from
         // the depth stencil
@@ -1969,41 +1966,33 @@
                                   GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level)
 {
     gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
-    if (!colorbuffer)
-    {
-        return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the color buffer from the frame buffer.");
-    }
+    ASSERT(colorbuffer);
 
-    RenderTarget11 *sourceRenderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer);
-    if (!sourceRenderTarget)
+    RenderTarget11 *sourceRenderTarget = NULL;
+    gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &sourceRenderTarget);
+    if (error.isError())
     {
-        return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the render target from the frame buffer.");
+        return error;
     }
+    ASSERT(sourceRenderTarget);
 
     ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView();
-    if (!source)
-    {
-        return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the render target view from the render target.");
-    }
+    ASSERT(source);
 
     TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage);
-    if (!storage11)
-    {
-        return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the texture storage from the destination.");
-    }
+    ASSERT(storage11);
 
     gl::ImageIndex index = gl::ImageIndex::Make2D(level);
-    RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(index));
-    if (!destRenderTarget)
+    RenderTarget *destRenderTarget = NULL;
+    error = storage11->getRenderTarget(index, &destRenderTarget);
+    if (error.isError())
     {
-        return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the render target from the destination storage.");
+        return error;
     }
+    ASSERT(destRenderTarget);
 
-    ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView();
-    if (!dest)
-    {
-        return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the render target view from the destination render target.");
-    }
+    ID3D11RenderTargetView *dest = RenderTarget11::makeRenderTarget11(destRenderTarget)->getRenderTargetView();
+    ASSERT(dest);
 
     gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1);
     gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1);
@@ -2013,8 +2002,7 @@
 
     // Use nearest filtering because source and destination are the same size for the direct
     // copy
-    gl::Error error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL,
-                                         destFormat, GL_NEAREST);
+    mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, destFormat, GL_NEAREST);
     if (error.isError())
     {
         return error;
@@ -2029,41 +2017,33 @@
                                     GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level)
 {
     gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
-    if (!colorbuffer)
-    {
-        return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the color buffer from the frame buffer.");
-    }
+    ASSERT(colorbuffer);
 
-    RenderTarget11 *sourceRenderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer);
-    if (!sourceRenderTarget)
+    RenderTarget11 *sourceRenderTarget = NULL;
+    gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &sourceRenderTarget);
+    if (error.isError())
     {
-        return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the render target from the frame buffer.");
+        return error;
     }
+    ASSERT(sourceRenderTarget);
 
     ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView();
-    if (!source)
-    {
-        return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the render target view from the render target.");
-    }
+    ASSERT(source);
 
     TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage);
-    if (!storage11)
-    {
-        return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the texture storage from the destination.");;
-    }
+    ASSERT(storage11);
 
     gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level);
-    RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(index));
-    if (!destRenderTarget)
+    RenderTarget *destRenderTarget = NULL;
+    error = storage11->getRenderTarget(index, &destRenderTarget);
+    if (error.isError())
     {
-        return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the render target from the destination storage.");
+        return error;
     }
+    ASSERT(destRenderTarget);
 
-    ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView();
-    if (!dest)
-    {
-        return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the render target view from the destination render target.");
-    }
+    ID3D11RenderTargetView *dest = RenderTarget11::makeRenderTarget11(destRenderTarget)->getRenderTargetView();
+    ASSERT(dest);
 
     gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1);
     gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1);
@@ -2073,8 +2053,7 @@
 
     // Use nearest filtering because source and destination are the same size for the direct
     // copy
-    gl::Error error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL,
-                                         destFormat, GL_NEAREST);
+    error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, destFormat, GL_NEAREST);
     if (error.isError())
     {
         return error;
@@ -2089,41 +2068,33 @@
                                   GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level)
 {
     gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
-    if (!colorbuffer)
-    {
-        return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the color buffer from the frame buffer.");
-    }
+    ASSERT(colorbuffer);
 
-    RenderTarget11 *sourceRenderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer);
-    if (!sourceRenderTarget)
+    RenderTarget11 *sourceRenderTarget = NULL;
+    gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &sourceRenderTarget);
+    if (error.isError())
     {
-        return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the render target from the frame buffer.");
+        return error;
     }
+    ASSERT(sourceRenderTarget);
 
     ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView();
-    if (!source)
-    {
-        return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the render target view from the render target.");
-    }
+    ASSERT(source);
 
     TextureStorage11_3D *storage11 = TextureStorage11_3D::makeTextureStorage11_3D(storage);
-    if (!storage11)
-    {
-        return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the texture storage from the destination.");
-    }
+    ASSERT(storage11);
 
     gl::ImageIndex index = gl::ImageIndex::Make3D(level, zOffset);
-    RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(index));
-    if (!destRenderTarget)
+    RenderTarget *destRenderTarget = NULL;
+    error = storage11->getRenderTarget(index, &destRenderTarget);
+    if (error.isError())
     {
-        return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the render target from the destination storage.");
+        return error;
     }
+    ASSERT(destRenderTarget);
 
-    ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView();
-    if (!dest)
-    {
-        return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the render target view from the destination render target.");
-    }
+    ID3D11RenderTargetView *dest = RenderTarget11::makeRenderTarget11(destRenderTarget)->getRenderTargetView();
+    ASSERT(dest);
 
     gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1);
     gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1);
@@ -2133,8 +2104,7 @@
 
     // Use nearest filtering because source and destination are the same size for the direct
     // copy
-    gl::Error error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL,
-                                         destFormat, GL_NEAREST);
+    error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, destFormat, GL_NEAREST);
     if (error.isError())
     {
         return error;
@@ -2149,43 +2119,33 @@
                                        GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level)
 {
     gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
-    if (!colorbuffer)
-    {
-        return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the color buffer from the frame buffer.");
-    }
+    ASSERT(colorbuffer);
 
-    RenderTarget11 *sourceRenderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer);
-    if (!sourceRenderTarget)
+    RenderTarget11 *sourceRenderTarget = NULL;
+    gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &sourceRenderTarget);
+    if (error.isError())
     {
-        return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the render target from the frame buffer.");
+        return error;
     }
+    ASSERT(sourceRenderTarget);
 
     ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView();
-    if (!source)
-    {
-        return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the render target view from the render target.");
-    }
+    ASSERT(source);
 
     TextureStorage11_2DArray *storage11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(storage);
-    if (!storage11)
-    {
-        SafeRelease(source);
-        return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the texture storage from the destination.");
-    }
+    ASSERT(storage11);
 
     gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, zOffset);
-    RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(index));
-    if (!destRenderTarget)
+    RenderTarget *destRenderTarget = NULL;
+    error = storage11->getRenderTarget(index, &destRenderTarget);
+    if (error.isError())
     {
-        SafeRelease(source);
-        return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the render target from the destination storage.");
+        return error;
     }
+    ASSERT(destRenderTarget);
 
-    ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView();
-    if (!dest)
-    {
-        return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the render target view from the destination render target.");
-    }
+    ID3D11RenderTargetView *dest = RenderTarget11::makeRenderTarget11(destRenderTarget)->getRenderTargetView();
+    ASSERT(dest);
 
     gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1);
     gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1);
@@ -2195,8 +2155,7 @@
 
     // Use nearest filtering because source and destination are the same size for the direct
     // copy
-    gl::Error error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL,
-                                         destFormat, GL_NEAREST);
+    error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, destFormat, GL_NEAREST);
     if (error.isError())
     {
         return error;
@@ -2544,22 +2503,30 @@
     return mPixelTransfer->copyBufferToTexture(unpack, offset, destRenderTarget, destinationFormat, sourcePixelsType, destArea);
 }
 
-bool Renderer11::getRenderTargetResource(gl::FramebufferAttachment *colorbuffer, unsigned int *subresourceIndexOut, ID3D11Texture2D **texture2DOut)
-{
-    ASSERT(colorbuffer != NULL);
+gl::Error Renderer11::getRenderTargetResource(gl::FramebufferAttachment *colorbuffer, unsigned int *subresourceIndexOut, ID3D11Texture2D **texture2DOut)
 
-    RenderTarget11 *renderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer);
-    if (!renderTarget)
+{
+    ASSERT(colorbuffer);
+
+    RenderTarget11 *renderTarget = NULL;
+    gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &renderTarget);
+    if (error.isError())
     {
-        return false;
+        return error;
     }
 
     ID3D11Resource *renderTargetResource = renderTarget->getTexture();
+    ASSERT(renderTargetResource);
 
     *subresourceIndexOut = renderTarget->getSubresourceIndex();
     *texture2DOut = d3d11::DynamicCastComObject<ID3D11Texture2D>(renderTargetResource);
 
-    return (*texture2DOut != NULL);
+    if (!(*texture2DOut))
+    {
+        return gl::Error(GL_OUT_OF_MEMORY, "Failed to query the ID3D11Texture2D from a RenderTarget");
+    }
+
+    return gl::Error(GL_NO_ERROR);
 }
 
 gl::Error Renderer11::blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
@@ -2568,28 +2535,33 @@
     if (blitRenderTarget)
     {
         gl::FramebufferAttachment *readBuffer = readTarget->getReadColorbuffer();
-        if (!readBuffer)
-        {
-            return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the read buffer from the read framebuffer.");
-        }
+        ASSERT(readBuffer);
 
-        RenderTarget *readRenderTarget = GetAttachmentRenderTarget(readBuffer);
+        RenderTarget *readRenderTarget = NULL;
+        gl::Error error = GetAttachmentRenderTarget(readBuffer, &readRenderTarget);
+        if (error.isError())
+        {
+            return error;
+        }
+        ASSERT(readRenderTarget);
 
         for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
         {
             if (drawTarget->isEnabledColorAttachment(colorAttachment))
             {
                 gl::FramebufferAttachment *drawBuffer = drawTarget->getColorbuffer(colorAttachment);
+                ASSERT(drawBuffer);
 
-                if (!drawBuffer)
+                RenderTarget *drawRenderTarget = NULL;
+                error = GetAttachmentRenderTarget(drawBuffer, &drawRenderTarget);
+                if (error.isError())
                 {
-                    return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the draw buffer from the draw framebuffer.");
+                    return error;
                 }
+                ASSERT(drawRenderTarget);
 
-                RenderTarget *drawRenderTarget = GetAttachmentRenderTarget(drawBuffer);
-
-                gl::Error error = blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter,
-                                                       scissor, blitRenderTarget, false, false);
+                error = blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter, scissor, blitRenderTarget,
+                                             false, false);
                 if (error.isError())
                 {
                     return error;
@@ -2601,23 +2573,29 @@
     if (blitDepth || blitStencil)
     {
         gl::FramebufferAttachment *readBuffer = readTarget->getDepthOrStencilbuffer();
-        if (!readBuffer)
+        ASSERT(readBuffer);
+
+        RenderTarget *readRenderTarget = NULL;
+        gl::Error error = GetAttachmentRenderTarget(readBuffer, &readRenderTarget);
+        if (error.isError())
         {
-            return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the read depth-stencil buffer from the read framebuffer.");
+            return error;
         }
+        ASSERT(readRenderTarget);
 
         gl::FramebufferAttachment *drawBuffer = drawTarget->getDepthOrStencilbuffer();
-        if (!drawBuffer)
+        ASSERT(drawBuffer);
+
+        RenderTarget *drawRenderTarget = NULL;
+        error = GetAttachmentRenderTarget(drawBuffer, &drawRenderTarget);
+        if (error.isError())
         {
-            return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the draw depth-stencil buffer from the draw framebuffer.");
+            return error;
         }
+        ASSERT(drawRenderTarget);
 
-        RenderTarget *readRenderTarget = GetAttachmentRenderTarget(readBuffer);
-        RenderTarget *drawRenderTarget = GetAttachmentRenderTarget(drawBuffer);
-        ASSERT(readRenderTarget && drawRenderTarget);
-
-        gl::Error error = blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter, scissor,
-                                               false, blitDepth, blitStencil);
+        error = blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter, scissor, false,
+                                     blitDepth, blitStencil);
         if (error.isError())
         {
             return error;
@@ -2636,41 +2614,47 @@
     unsigned int subresourceIndex = 0;
 
     gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
+    ASSERT(colorbuffer);
 
-    if (colorbuffer && getRenderTargetResource(colorbuffer, &subresourceIndex, &colorBufferTexture))
+    gl::Error error = getRenderTargetResource(colorbuffer, &subresourceIndex, &colorBufferTexture);
+    if (error.isError())
     {
-        gl::Rectangle area;
-        area.x = x;
-        area.y = y;
-        area.width = width;
-        area.height = height;
-
-        gl::Buffer *packBuffer = pack.pixelBuffer.get();
-        if (packBuffer != NULL)
-        {
-            rx::Buffer11 *packBufferStorage = Buffer11::makeBuffer11(packBuffer->getImplementation());
-            PackPixelsParams packParams(area, format, type, outputPitch, pack, reinterpret_cast<ptrdiff_t>(pixels));
-
-            gl::Error error = packBufferStorage->packPixels(colorBufferTexture, subresourceIndex, packParams);
-            if (error.isError())
-            {
-                return error;
-            }
-
-            packBuffer->getIndexRangeCache()->clear();
-        }
-        else
-        {
-            gl::Error error = readTextureData(colorBufferTexture, subresourceIndex, area, format, type, outputPitch, pack, pixels);
-            if (error.isError())
-            {
-                return error;
-            }
-        }
-
-        SafeRelease(colorBufferTexture);
+        return error;
     }
 
+    gl::Rectangle area;
+    area.x = x;
+    area.y = y;
+    area.width = width;
+    area.height = height;
+
+    gl::Buffer *packBuffer = pack.pixelBuffer.get();
+    if (packBuffer != NULL)
+    {
+        rx::Buffer11 *packBufferStorage = Buffer11::makeBuffer11(packBuffer->getImplementation());
+        PackPixelsParams packParams(area, format, type, outputPitch, pack, reinterpret_cast<ptrdiff_t>(pixels));
+
+        error = packBufferStorage->packPixels(colorBufferTexture, subresourceIndex, packParams);
+        if (error.isError())
+        {
+            SafeRelease(colorBufferTexture);
+            return error;
+        }
+
+        packBuffer->getIndexRangeCache()->clear();
+    }
+    else
+    {
+        error = readTextureData(colorBufferTexture, subresourceIndex, area, format, type, outputPitch, pack, pixels);
+        if (error.isError())
+        {
+            SafeRelease(colorBufferTexture);
+            return error;
+        }
+    }
+
+    SafeRelease(colorBufferTexture);
+
     return gl::Error(GL_NO_ERROR);
 }
 
diff --git a/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
index ff49a8d..a7719f9 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
+++ b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
@@ -190,7 +190,8 @@
     virtual gl::Error fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,
                                               GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea);
 
-    bool getRenderTargetResource(gl::FramebufferAttachment *colorbuffer, unsigned int *subresourceIndexOut, ID3D11Texture2D **texture2DOut);
+    gl::Error getRenderTargetResource(gl::FramebufferAttachment *colorbuffer, unsigned int *subresourceIndexOut, ID3D11Texture2D **texture2DOut);
+
     void unapplyRenderTargets();
     void setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView);
     gl::Error packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams &params, uint8_t *pixelsOut);
diff --git a/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp b/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp
index c21430c..4f881ce 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp
@@ -375,28 +375,32 @@
 
     invalidateSwizzleCacheLevel(destIndex.mipIndex);
 
-    RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(sourceIndex));
-    RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(destIndex));
-
-    if (source && dest)
+    RenderTarget *source = NULL;
+    gl::Error error = getRenderTarget(sourceIndex, &source);
+    if (error.isError())
     {
-        ID3D11ShaderResourceView *sourceSRV = source->getShaderResourceView();
-        ID3D11RenderTargetView *destRTV = dest->getRenderTargetView();
-
-        if (sourceSRV && destRTV)
-        {
-            gl::Box sourceArea(0, 0, 0, source->getWidth(), source->getHeight(), source->getDepth());
-            gl::Extents sourceSize(source->getWidth(), source->getHeight(), source->getDepth());
-
-            gl::Box destArea(0, 0, 0, dest->getWidth(), dest->getHeight(), dest->getDepth());
-            gl::Extents destSize(dest->getWidth(), dest->getHeight(), dest->getDepth());
-
-            Blit11 *blitter = mRenderer->getBlitter();
-
-            blitter->copyTexture(sourceSRV, sourceArea, sourceSize, destRTV, destArea, destSize, NULL,
-                                 gl::GetInternalFormatInfo(source->getInternalFormat()).format, GL_LINEAR);
-        }
+        return;
     }
+
+    RenderTarget *dest = NULL;
+    error = getRenderTarget(destIndex, &dest);
+    if (error.isError())
+    {
+        return;
+    }
+
+    ID3D11ShaderResourceView *sourceSRV = RenderTarget11::makeRenderTarget11(source)->getShaderResourceView();
+    ID3D11RenderTargetView *destRTV = RenderTarget11::makeRenderTarget11(dest)->getRenderTargetView();
+
+    gl::Box sourceArea(0, 0, 0, source->getWidth(), source->getHeight(), source->getDepth());
+    gl::Extents sourceSize(source->getWidth(), source->getHeight(), source->getDepth());
+
+    gl::Box destArea(0, 0, 0, dest->getWidth(), dest->getHeight(), dest->getDepth());
+    gl::Extents destSize(dest->getWidth(), dest->getHeight(), dest->getDepth());
+
+    Blit11 *blitter = mRenderer->getBlitter();
+    blitter->copyTexture(sourceSRV, sourceArea, sourceSize, destRTV, destArea, destSize, NULL,
+                         gl::GetInternalFormatInfo(source->getInternalFormat()).format, GL_LINEAR);
 }
 
 void TextureStorage11::verifySwizzleExists(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha)
@@ -727,82 +731,78 @@
     return mTexture;
 }
 
-RenderTarget *TextureStorage11_2D::getRenderTarget(const gl::ImageIndex &index)
+gl::Error TextureStorage11_2D::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
 {
     ASSERT(!index.hasLayer());
 
     int level = index.mipIndex;
+    ASSERT(level >= 0 && level < getLevelCount());
 
-    if (level >= 0 && level < getLevelCount())
+    if (!mRenderTarget[level])
     {
-        if (!mRenderTarget[level])
+        ID3D11ShaderResourceView *srv = NULL;
+        gl::Error error = getSRVLevel(level, &srv);
+        if (error.isError())
         {
-            ID3D11ShaderResourceView *srv = NULL;
-            if (getSRVLevel(level, &srv).isError())
-            {
-                return NULL;
-            }
-
-            if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
-            {
-                ID3D11Device *device = mRenderer->getDevice();
-
-                D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
-                rtvDesc.Format = mRenderTargetFormat;
-                rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
-                rtvDesc.Texture2D.MipSlice = mTopLevel + level;
-
-                ID3D11RenderTargetView *rtv;
-                HRESULT result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
-
-                if (result == E_OUTOFMEMORY)
-                {
-                    return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
-                }
-                ASSERT(SUCCEEDED(result));
-
-                mRenderTarget[level] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1);
-
-                // RenderTarget will take ownership of these resources
-                SafeRelease(rtv);
-            }
-            else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN)
-            {
-                ID3D11Device *device = mRenderer->getDevice();
-
-                D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
-                dsvDesc.Format = mDepthStencilFormat;
-                dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
-                dsvDesc.Texture2D.MipSlice = mTopLevel + level;
-                dsvDesc.Flags = 0;
-
-                ID3D11DepthStencilView *dsv;
-                HRESULT result = device->CreateDepthStencilView(mTexture, &dsvDesc, &dsv);
-
-                if (result == E_OUTOFMEMORY)
-                {
-                    SafeRelease(srv);
-                    return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
-                }
-                ASSERT(SUCCEEDED(result));
-
-                mRenderTarget[level] = new RenderTarget11(mRenderer, dsv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1);
-
-                // RenderTarget will take ownership of these resources
-                SafeRelease(dsv);
-            }
-            else
-            {
-                UNREACHABLE();
-            }
+            return error;
         }
 
-        return mRenderTarget[level];
+        if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
+        {
+            ID3D11Device *device = mRenderer->getDevice();
+
+            D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+            rtvDesc.Format = mRenderTargetFormat;
+            rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
+            rtvDesc.Texture2D.MipSlice = mTopLevel + level;
+
+            ID3D11RenderTargetView *rtv;
+            HRESULT result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
+
+            ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+            if (FAILED(result))
+            {
+                return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result);
+            }
+
+            mRenderTarget[level] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1);
+
+            // RenderTarget will take ownership of these resources
+            SafeRelease(rtv);
+        }
+        else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN)
+        {
+            ID3D11Device *device = mRenderer->getDevice();
+
+            D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
+            dsvDesc.Format = mDepthStencilFormat;
+            dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
+            dsvDesc.Texture2D.MipSlice = mTopLevel + level;
+            dsvDesc.Flags = 0;
+
+            ID3D11DepthStencilView *dsv;
+            HRESULT result = device->CreateDepthStencilView(mTexture, &dsvDesc, &dsv);
+
+            ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+            if (FAILED(result))
+            {
+                return gl::Error(GL_OUT_OF_MEMORY,"Failed to create internal depth stencil view for texture storage, result: 0x%X.", result);
+            }
+
+            mRenderTarget[level] = new RenderTarget11(mRenderer, dsv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1);
+
+            // RenderTarget will take ownership of these resources
+            SafeRelease(dsv);
+        }
+        else
+        {
+            UNREACHABLE();
+        }
     }
-    else
-    {
-        return NULL;
-    }
+
+    ASSERT(outRT);
+    *outRT = mRenderTarget[level];
+    return gl::Error(GL_NO_ERROR);
 }
 
 gl::Error TextureStorage11_2D::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
@@ -1106,98 +1106,96 @@
     return mTexture;
 }
 
-RenderTarget *TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index)
+gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
 {
     int faceIndex = index.layerIndex;
     int level = index.mipIndex;
 
-    if (level >= 0 && level < getLevelCount())
+    ASSERT(level >= 0 && level < getLevelCount());
+    ASSERT(faceIndex >= 0 && faceIndex < 6);
+
+    if (!mRenderTarget[faceIndex][level])
     {
-        if (!mRenderTarget[faceIndex][level])
+        ID3D11Device *device = mRenderer->getDevice();
+        HRESULT result;
+
+        D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+        srvDesc.Format = mShaderResourceFormat;
+        srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; // Will be used with Texture2D sampler, not TextureCube
+        srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + level;
+        srvDesc.Texture2DArray.MipLevels = 1;
+        srvDesc.Texture2DArray.FirstArraySlice = faceIndex;
+        srvDesc.Texture2DArray.ArraySize = 1;
+
+        ID3D11ShaderResourceView *srv;
+        result = device->CreateShaderResourceView(mTexture, &srvDesc, &srv);
+
+        ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+        if (FAILED(result))
         {
-            ID3D11Device *device = mRenderer->getDevice();
-            HRESULT result;
-
-            D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
-            srvDesc.Format = mShaderResourceFormat;
-            srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; // Will be used with Texture2D sampler, not TextureCube
-            srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + level;
-            srvDesc.Texture2DArray.MipLevels = 1;
-            srvDesc.Texture2DArray.FirstArraySlice = faceIndex;
-            srvDesc.Texture2DArray.ArraySize = 1;
-
-            ID3D11ShaderResourceView *srv;
-            result = device->CreateShaderResourceView(mTexture, &srvDesc, &srv);
-
-            if (result == E_OUTOFMEMORY)
-            {
-                return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
-            }
-            ASSERT(SUCCEEDED(result));
-
-            if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
-            {
-                D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
-                rtvDesc.Format = mRenderTargetFormat;
-                rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
-                rtvDesc.Texture2DArray.MipSlice = mTopLevel + level;
-                rtvDesc.Texture2DArray.FirstArraySlice = faceIndex;
-                rtvDesc.Texture2DArray.ArraySize = 1;
-
-                ID3D11RenderTargetView *rtv;
-                result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
-
-                if (result == E_OUTOFMEMORY)
-                {
-                    SafeRelease(srv);
-                    return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
-                }
-                ASSERT(SUCCEEDED(result));
-
-                mRenderTarget[faceIndex][level] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1);
-
-                // RenderTarget will take ownership of these resources
-                SafeRelease(rtv);
-                SafeRelease(srv);
-            }
-            else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN)
-            {
-                D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
-                dsvDesc.Format = mDepthStencilFormat;
-                dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
-                dsvDesc.Flags = 0;
-                dsvDesc.Texture2DArray.MipSlice = mTopLevel + level;
-                dsvDesc.Texture2DArray.FirstArraySlice = faceIndex;
-                dsvDesc.Texture2DArray.ArraySize = 1;
-
-                ID3D11DepthStencilView *dsv;
-                result = device->CreateDepthStencilView(mTexture, &dsvDesc, &dsv);
-
-                if (result == E_OUTOFMEMORY)
-                {
-                    SafeRelease(srv);
-                    return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
-                }
-                ASSERT(SUCCEEDED(result));
-
-                mRenderTarget[faceIndex][level] = new RenderTarget11(mRenderer, dsv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1);
-
-                // RenderTarget will take ownership of these resources
-                SafeRelease(dsv);
-                SafeRelease(srv);
-            }
-            else
-            {
-                UNREACHABLE();
-            }
+            return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal shader resource view for texture storage, result: 0x%X.", result);
         }
 
-        return mRenderTarget[faceIndex][level];
+        if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
+        {
+            D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+            rtvDesc.Format = mRenderTargetFormat;
+            rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
+            rtvDesc.Texture2DArray.MipSlice = mTopLevel + level;
+            rtvDesc.Texture2DArray.FirstArraySlice = faceIndex;
+            rtvDesc.Texture2DArray.ArraySize = 1;
+
+            ID3D11RenderTargetView *rtv;
+            result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
+
+            ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+            if (FAILED(result))
+            {
+                SafeRelease(srv);
+                return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result);
+            }
+
+            mRenderTarget[faceIndex][level] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1);
+
+            // RenderTarget will take ownership of these resources
+            SafeRelease(rtv);
+            SafeRelease(srv);
+        }
+        else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN)
+        {
+            D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
+            dsvDesc.Format = mDepthStencilFormat;
+            dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
+            dsvDesc.Flags = 0;
+            dsvDesc.Texture2DArray.MipSlice = mTopLevel + level;
+            dsvDesc.Texture2DArray.FirstArraySlice = faceIndex;
+            dsvDesc.Texture2DArray.ArraySize = 1;
+
+            ID3D11DepthStencilView *dsv;
+            result = device->CreateDepthStencilView(mTexture, &dsvDesc, &dsv);
+
+            ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+            if (FAILED(result))
+            {
+                SafeRelease(srv);
+                return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal depth stencil view for texture storage, result: 0x%X.", result);
+            }
+
+            mRenderTarget[faceIndex][level] = new RenderTarget11(mRenderer, dsv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1);
+
+            // RenderTarget will take ownership of these resources
+            SafeRelease(dsv);
+            SafeRelease(srv);
+        }
+        else
+        {
+            UNREACHABLE();
+        }
     }
-    else
-    {
-        return NULL;
-    }
+
+    ASSERT(outRT);
+    *outRT = mRenderTarget[faceIndex][level];
+    return gl::Error(GL_NO_ERROR);
 }
 
 gl::Error TextureStorage11_Cube::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
@@ -1521,93 +1519,93 @@
     return gl::Error(GL_NO_ERROR);
 }
 
-RenderTarget *TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index)
+gl::Error TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
 {
     int mipLevel = index.mipIndex;
+    ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
 
-    if (mipLevel >= 0 && mipLevel < getLevelCount())
+    ASSERT(mRenderTargetFormat != DXGI_FORMAT_UNKNOWN);
+
+    if (!index.hasLayer())
     {
-        ASSERT(mRenderTargetFormat != DXGI_FORMAT_UNKNOWN);
-
-        if (!index.hasLayer())
+        if (!mLevelRenderTargets[mipLevel])
         {
-            if (!mLevelRenderTargets[mipLevel])
+            ID3D11ShaderResourceView *srv = NULL;
+            gl::Error error = getSRVLevel(mipLevel, &srv);
+            if (error.isError())
             {
-                ID3D11ShaderResourceView *srv = NULL;
-                if (getSRVLevel(mipLevel, &srv).isError())
-                {
-                    return NULL;
-                }
-
-                ID3D11Device *device = mRenderer->getDevice();
-
-                D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
-                rtvDesc.Format = mRenderTargetFormat;
-                rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
-                rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
-                rtvDesc.Texture3D.FirstWSlice = 0;
-                rtvDesc.Texture3D.WSize = -1;
-
-                ID3D11RenderTargetView *rtv;
-                HRESULT result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
-
-                if (result == E_OUTOFMEMORY)
-                {
-                    SafeRelease(srv);
-                    return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
-                }
-                ASSERT(SUCCEEDED(result));
-
-                mLevelRenderTargets[mipLevel] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), getLevelDepth(mipLevel));
-
-                // RenderTarget will take ownership of these resources
-                SafeRelease(rtv);
+                return error;
             }
 
-            return mLevelRenderTargets[mipLevel];
-        }
-        else
-        {
-            int layer = index.layerIndex;
+            ID3D11Device *device = mRenderer->getDevice();
 
-            LevelLayerKey key(mipLevel, layer);
-            if (mLevelLayerRenderTargets.find(key) == mLevelLayerRenderTargets.end())
+            D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+            rtvDesc.Format = mRenderTargetFormat;
+            rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
+            rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
+            rtvDesc.Texture3D.FirstWSlice = 0;
+            rtvDesc.Texture3D.WSize = -1;
+
+            ID3D11RenderTargetView *rtv;
+            HRESULT result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
+
+            ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+            if (FAILED(result))
             {
-                ID3D11Device *device = mRenderer->getDevice();
-                HRESULT result;
-
-                // TODO, what kind of SRV is expected here?
-                ID3D11ShaderResourceView *srv = NULL;
-
-                D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
-                rtvDesc.Format = mRenderTargetFormat;
-                rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
-                rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
-                rtvDesc.Texture3D.FirstWSlice = layer;
-                rtvDesc.Texture3D.WSize = 1;
-
-                ID3D11RenderTargetView *rtv;
-                result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
-
-                if (result == E_OUTOFMEMORY)
-                {
-                    SafeRelease(srv);
-                    return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
-                }
-                ASSERT(SUCCEEDED(result));
-
-                mLevelLayerRenderTargets[key] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1);
-
-                // RenderTarget will take ownership of these resources
-                SafeRelease(rtv);
                 SafeRelease(srv);
+                return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result);
             }
 
-            return mLevelLayerRenderTargets[key];
-        }
-    }
+            mLevelRenderTargets[mipLevel] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), getLevelDepth(mipLevel));
 
-    return NULL;
+            // RenderTarget will take ownership of these resources
+            SafeRelease(rtv);
+        }
+
+        ASSERT(outRT);
+        *outRT = mLevelRenderTargets[mipLevel];
+        return gl::Error(GL_NO_ERROR);
+    }
+    else
+    {
+        int layer = index.layerIndex;
+
+        LevelLayerKey key(mipLevel, layer);
+        if (mLevelLayerRenderTargets.find(key) == mLevelLayerRenderTargets.end())
+        {
+            ID3D11Device *device = mRenderer->getDevice();
+            HRESULT result;
+
+            // TODO, what kind of SRV is expected here?
+            ID3D11ShaderResourceView *srv = NULL;
+
+            D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+            rtvDesc.Format = mRenderTargetFormat;
+            rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
+            rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
+            rtvDesc.Texture3D.FirstWSlice = layer;
+            rtvDesc.Texture3D.WSize = 1;
+
+            ID3D11RenderTargetView *rtv;
+            result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
+
+            ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+            if (FAILED(result))
+            {
+                SafeRelease(srv); return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result);
+            }
+            ASSERT(SUCCEEDED(result));
+
+            mLevelLayerRenderTargets[key] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1);
+
+            // RenderTarget will take ownership of these resources
+            SafeRelease(rtv);
+        }
+
+        ASSERT(outRT);
+        *outRT = mLevelLayerRenderTargets[key];
+        return gl::Error(GL_NO_ERROR);
+    }
 }
 
 gl::Error TextureStorage11_3D::getSwizzleTexture(ID3D11Resource **outTexture)
@@ -1890,75 +1888,72 @@
     return gl::Error(GL_NO_ERROR);
 }
 
-RenderTarget *TextureStorage11_2DArray::getRenderTarget(const gl::ImageIndex &index)
+gl::Error TextureStorage11_2DArray::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
 {
     ASSERT(index.hasLayer());
 
     int mipLevel = index.mipIndex;
     int layer = index.layerIndex;
 
-    if (mipLevel >= 0 && mipLevel < getLevelCount())
+    ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
+
+    LevelLayerKey key(mipLevel, layer);
+    if (mRenderTargets.find(key) == mRenderTargets.end())
     {
-        LevelLayerKey key(mipLevel, layer);
-        if (mRenderTargets.find(key) == mRenderTargets.end())
+        ID3D11Device *device = mRenderer->getDevice();
+        HRESULT result;
+
+        D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+        srvDesc.Format = mShaderResourceFormat;
+        srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
+        srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + mipLevel;
+        srvDesc.Texture2DArray.MipLevels = 1;
+        srvDesc.Texture2DArray.FirstArraySlice = layer;
+        srvDesc.Texture2DArray.ArraySize = 1;
+
+        ID3D11ShaderResourceView *srv;
+        result = device->CreateShaderResourceView(mTexture, &srvDesc, &srv);
+
+        ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+        if (FAILED(result))
         {
-            ID3D11Device *device = mRenderer->getDevice();
-            HRESULT result;
-
-            D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
-            srvDesc.Format = mShaderResourceFormat;
-            srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
-            srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + mipLevel;
-            srvDesc.Texture2DArray.MipLevels = 1;
-            srvDesc.Texture2DArray.FirstArraySlice = layer;
-            srvDesc.Texture2DArray.ArraySize = 1;
-
-            ID3D11ShaderResourceView *srv;
-            result = device->CreateShaderResourceView(mTexture, &srvDesc, &srv);
-
-            if (result == E_OUTOFMEMORY)
-            {
-                return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
-            }
-            ASSERT(SUCCEEDED(result));
-
-            if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
-            {
-                D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
-                rtvDesc.Format = mRenderTargetFormat;
-                rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
-                rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
-                rtvDesc.Texture2DArray.FirstArraySlice = layer;
-                rtvDesc.Texture2DArray.ArraySize = 1;
-
-                ID3D11RenderTargetView *rtv;
-                result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
-
-                if (result == E_OUTOFMEMORY)
-                {
-                    SafeRelease(srv);
-                    return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
-                }
-                ASSERT(SUCCEEDED(result));
-
-                mRenderTargets[key] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1);
-
-                // RenderTarget will take ownership of these resources
-                SafeRelease(rtv);
-                SafeRelease(srv);
-            }
-            else
-            {
-                UNREACHABLE();
-            }
+            return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal shader resource view for texture storage, result: 0x%X.", result);
         }
 
-        return mRenderTargets[key];
+        if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
+        {
+            D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+            rtvDesc.Format = mRenderTargetFormat;
+            rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
+            rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
+            rtvDesc.Texture2DArray.FirstArraySlice = layer;
+            rtvDesc.Texture2DArray.ArraySize = 1;
+
+            ID3D11RenderTargetView *rtv;
+            result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
+
+            ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+            if (FAILED(result))
+            {
+                SafeRelease(srv);
+                return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result);
+            }
+
+            mRenderTargets[key] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1);
+
+            // RenderTarget will take ownership of these resources
+            SafeRelease(rtv);
+            SafeRelease(srv);
+        }
+        else
+        {
+            UNREACHABLE();
+        }
     }
-    else
-    {
-        return NULL;
-    }
+
+    ASSERT(outRT);
+    *outRT = mRenderTargets[key];
+    return gl::Error(GL_NO_ERROR);
 }
 
 gl::Error TextureStorage11_2DArray::getSwizzleTexture(ID3D11Resource **outTexture)
diff --git a/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h b/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h
index 084dce7..d524f36 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h
+++ b/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h
@@ -43,7 +43,7 @@
 
     virtual ID3D11Resource *getResource() const = 0;
     virtual gl::Error getSRV(const gl::SamplerState &samplerState, ID3D11ShaderResourceView **outSRV);
-    virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index) = 0;
+    virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) = 0;
 
     virtual void generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex);
 
@@ -148,7 +148,7 @@
     static TextureStorage11_2D *makeTextureStorage11_2D(TextureStorage *storage);
 
     virtual ID3D11Resource *getResource() const;
-    virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
+    virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
 
     virtual void associateImage(Image11* image, const gl::ImageIndex &index);
     virtual void disassociateImage(const gl::ImageIndex &index, Image11* expectedImage);
@@ -183,7 +183,7 @@
     static TextureStorage11_Cube *makeTextureStorage11_Cube(TextureStorage *storage);
 
     virtual ID3D11Resource *getResource() const;
-    virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
+    virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
 
     virtual void associateImage(Image11* image, const gl::ImageIndex &index);
     virtual void disassociateImage(const gl::ImageIndex &index, Image11* expectedImage);
@@ -221,7 +221,7 @@
     virtual ID3D11Resource *getResource() const;
 
     // Handles both layer and non-layer RTs
-    virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
+    virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
 
     virtual void associateImage(Image11* image, const gl::ImageIndex &index);
     virtual void disassociateImage(const gl::ImageIndex &index, Image11* expectedImage);
@@ -261,7 +261,7 @@
     static TextureStorage11_2DArray *makeTextureStorage11_2DArray(TextureStorage *storage);
 
     virtual ID3D11Resource *getResource() const;
-    virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
+    virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
 
     virtual void associateImage(Image11* image, const gl::ImageIndex &index);
     virtual void disassociateImage(const gl::ImageIndex &index, Image11* expectedImage);
diff --git a/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp b/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp
index 3164ce9..9ffc32e 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp
@@ -1066,10 +1066,16 @@
 #endif
 }
 
-RenderTarget11 *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment)
+gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget11 **outRT)
 {
-    RenderTarget *renderTarget = rx::GetAttachmentRenderTarget(attachment);
-    return RenderTarget11::makeRenderTarget11(renderTarget);
+    RenderTarget *renderTarget = NULL;
+    gl::Error error = rx::GetAttachmentRenderTarget(attachment, &renderTarget);
+    if (error.isError())
+    {
+        return error;
+    }
+    *outRT = RenderTarget11::makeRenderTarget11(renderTarget);
+    return gl::Error(GL_NO_ERROR);
 }
 
 Workarounds GenerateWorkarounds()
diff --git a/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.h b/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.h
index 987e9ab..9df9c95 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.h
+++ b/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.h
@@ -12,6 +12,7 @@
 
 #include "libGLESv2/angletypes.h"
 #include "libGLESv2/Caps.h"
+#include "libGLESv2/Error.h"
 
 #include <vector>
 
@@ -177,7 +178,7 @@
     context->Unmap(constantBuffer, 0);
 }
 
-RenderTarget11 *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment);
+gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget11 **outRT);
 
 Workarounds GenerateWorkarounds();
 
diff --git a/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp b/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp
index 20071dd..3187076 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp
@@ -208,32 +208,23 @@
 
 gl::Error Blit9::copy2D(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level)
 {
-    RenderTarget9 *renderTarget = NULL;
-    IDirect3DSurface9 *source = NULL;
     gl::FramebufferAttachment *colorbuffer = framebuffer->getColorbuffer(0);
+    ASSERT(colorbuffer);
 
-    if (colorbuffer)
+    RenderTarget9 *renderTarget9 = NULL;
+    gl::Error error = d3d9::GetAttachmentRenderTarget(colorbuffer, &renderTarget9);
+    if (error.isError())
     {
-        renderTarget = d3d9::GetAttachmentRenderTarget(colorbuffer);
+        return error;
     }
+    ASSERT(renderTarget9);
 
-    if (renderTarget)
-    {
-        source = renderTarget->getSurface();
-    }
-
-    if (!source)
-    {
-        return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the internal render target for texture blit.");
-    }
+    IDirect3DSurface9 *source = renderTarget9->getSurface();
+    ASSERT(source);
 
     TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage);
     IDirect3DSurface9 *destSurface = storage9->getSurfaceLevel(level, true);
-    if (!destSurface)
-    {
-        SafeRelease(source);
-        return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the destination surface for texture blit.");
-    }
+    ASSERT(destSurface);
 
     gl::Error result = copy(source, sourceRect, destFormat, xoffset, yoffset, destSurface);
 
@@ -245,33 +236,23 @@
 
 gl::Error Blit9::copyCube(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level)
 {
-    RenderTarget9 *renderTarget = NULL;
-    IDirect3DSurface9 *source = NULL;
     gl::FramebufferAttachment *colorbuffer = framebuffer->getColorbuffer(0);
+    ASSERT(colorbuffer);
 
-    if (colorbuffer)
+    RenderTarget9 *renderTarget9 = NULL;
+    gl::Error error = d3d9::GetAttachmentRenderTarget(colorbuffer, &renderTarget9);
+    if (error.isError())
     {
-        renderTarget = d3d9::GetAttachmentRenderTarget(colorbuffer);
+        return error;
     }
+    ASSERT(renderTarget9);
 
-    if (renderTarget)
-    {
-        source = renderTarget->getSurface();
-    }
-
-    if (!source)
-    {
-        return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the internal render target for texture blit.");
-    }
+    IDirect3DSurface9 *source = renderTarget9->getSurface();
+    ASSERT(source);
 
     TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage);
     IDirect3DSurface9 *destSurface = storage9->getCubeMapSurface(target, level, true);
-
-    if (!destSurface)
-    {
-        SafeRelease(source);
-        return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the destination surface for texture blit.");
-    }
+    ASSERT(destSurface);
 
     gl::Error result = copy(source, sourceRect, destFormat, xoffset, yoffset, destSurface);
 
diff --git a/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp b/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp
index c687606..4d2b9b0 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp
@@ -479,17 +479,9 @@
     ASSERT(zoffset == 0);
 
     RenderTarget9 *renderTarget = RenderTarget9::makeRenderTarget9(source);
-    IDirect3DSurface9 *surface = NULL;
 
-    if (renderTarget)
-    {
-        surface = renderTarget->getSurface();
-    }
-
-    if (!surface)
-    {
-        return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the internal render target.");
-    }
+    IDirect3DSurface9 *surface = renderTarget->getSurface();
+    ASSERT(surface);
 
     IDirect3DDevice9 *device = mRenderer->getDevice();
 
diff --git a/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
index e1dd941..c4a2e65 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
@@ -1191,28 +1191,23 @@
     {
         attachment = getNullColorbuffer(framebuffer->getDepthbuffer());
     }
-    if (!attachment)
-    {
-        return gl::Error(GL_OUT_OF_MEMORY, "Unable to locate renderbuffer for FBO.");
-    }
+    ASSERT(attachment);
 
     bool renderTargetChanged = false;
     unsigned int renderTargetSerial = GetAttachmentSerial(attachment);
     if (renderTargetSerial != mAppliedRenderTargetSerial)
     {
         // Apply the render target on the device
-        IDirect3DSurface9 *renderTargetSurface = NULL;
-
-        RenderTarget9 *renderTarget = d3d9::GetAttachmentRenderTarget(attachment);
-        if (renderTarget)
+        RenderTarget9 *renderTarget = NULL;
+        gl::Error error = d3d9::GetAttachmentRenderTarget(attachment, &renderTarget);
+        if (error.isError())
         {
-            renderTargetSurface = renderTarget->getSurface();
+            return error;
         }
+        ASSERT(renderTarget);
 
-        if (!renderTargetSurface)
-        {
-            return gl::Error(GL_OUT_OF_MEMORY, "Internal render target pointer unexpectedly null.");
-        }
+        IDirect3DSurface9 *renderTargetSurface = renderTarget->getSurface();
+        ASSERT(renderTargetSurface);
 
         mDevice->SetRenderTarget(0, renderTargetSurface);
         SafeRelease(renderTargetSurface);
@@ -1244,18 +1239,16 @@
         // Apply the depth stencil on the device
         if (depthStencil)
         {
-            IDirect3DSurface9 *depthStencilSurface = NULL;
-            rx::RenderTarget9 *depthStencilRenderTarget = d3d9::GetAttachmentRenderTarget(depthStencil);
-
-            if (depthStencilRenderTarget)
+            RenderTarget9 *depthStencilRenderTarget = NULL;
+            gl::Error error = d3d9::GetAttachmentRenderTarget(depthStencil, &depthStencilRenderTarget);
+            if (error.isError())
             {
-                depthStencilSurface = depthStencilRenderTarget->getSurface();
+                return error;
             }
+            ASSERT(depthStencilRenderTarget);
 
-            if (!depthStencilSurface)
-            {
-                return gl::Error(GL_OUT_OF_MEMORY, "Internal depth stencil pointer unexpectedly null.");
-            }
+            IDirect3DSurface9 *depthStencilSurface = depthStencilRenderTarget->getSurface();
+            ASSERT(depthStencilSurface);
 
             mDevice->SetDepthStencilSurface(depthStencilSurface);
             SafeRelease(depthStencilSurface);
@@ -2447,34 +2440,33 @@
     if (blitRenderTarget)
     {
         gl::FramebufferAttachment *readBuffer = readFramebuffer->getColorbuffer(0);
-        gl::FramebufferAttachment *drawBuffer = drawFramebuffer->getColorbuffer(0);
+        ASSERT(readBuffer);
+
         RenderTarget9 *readRenderTarget = NULL;
+        gl::Error error = d3d9::GetAttachmentRenderTarget(readBuffer, &readRenderTarget);
+        if (error.isError())
+        {
+            return error;
+        }
+        ASSERT(readRenderTarget);
+
+        gl::FramebufferAttachment *drawBuffer = drawFramebuffer->getColorbuffer(0);
+        ASSERT(drawBuffer);
+
         RenderTarget9 *drawRenderTarget = NULL;
-        IDirect3DSurface9* readSurface = NULL;
-        IDirect3DSurface9* drawSurface = NULL;
+        error = d3d9::GetAttachmentRenderTarget(drawBuffer, &drawRenderTarget);
+        if (error.isError())
+        {
+            return error;
+        }
+        ASSERT(drawRenderTarget);
 
-        if (readBuffer)
-        {
-            readRenderTarget = d3d9::GetAttachmentRenderTarget(readBuffer);
-        }
-        if (drawBuffer)
-        {
-            drawRenderTarget = d3d9::GetAttachmentRenderTarget(drawBuffer);
-        }
+        // The getSurface calls do an AddRef so save them until after no errors are possible
+        IDirect3DSurface9* readSurface = readRenderTarget->getSurface();
+        ASSERT(readSurface);
 
-        if (readRenderTarget)
-        {
-            readSurface = readRenderTarget->getSurface();
-        }
-        if (drawRenderTarget)
-        {
-            drawSurface = drawRenderTarget->getSurface();
-        }
-
-        if (!readSurface || !drawSurface)
-        {
-            return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the internal render targets for the blit framebuffers.");
-        }
+        IDirect3DSurface9* drawSurface = drawRenderTarget->getSurface();
+        ASSERT(drawSurface);
 
         gl::Extents srcSize(readRenderTarget->getWidth(), readRenderTarget->getHeight(), 1);
         gl::Extents dstSize(drawRenderTarget->getWidth(), drawRenderTarget->getHeight(), 1);
@@ -2574,34 +2566,33 @@
     if (blitDepth || blitStencil)
     {
         gl::FramebufferAttachment *readBuffer = readFramebuffer->getDepthOrStencilbuffer();
-        gl::FramebufferAttachment *drawBuffer = drawFramebuffer->getDepthOrStencilbuffer();
+        ASSERT(readBuffer);
+
         RenderTarget9 *readDepthStencil = NULL;
+        gl::Error error = d3d9::GetAttachmentRenderTarget(readBuffer, &readDepthStencil);
+        if (error.isError())
+        {
+            return error;
+        }
+        ASSERT(readDepthStencil);
+
+        gl::FramebufferAttachment *drawBuffer = drawFramebuffer->getDepthOrStencilbuffer();
+        ASSERT(drawBuffer);
+
         RenderTarget9 *drawDepthStencil = NULL;
-        IDirect3DSurface9* readSurface = NULL;
-        IDirect3DSurface9* drawSurface = NULL;
+        error = d3d9::GetAttachmentRenderTarget(drawBuffer, &drawDepthStencil);
+        if (error.isError())
+        {
+            return error;
+        }
+        ASSERT(drawDepthStencil);
 
-        if (readBuffer)
-        {
-            readDepthStencil = d3d9::GetAttachmentRenderTarget(readBuffer);
-        }
-        if (drawBuffer)
-        {
-            drawDepthStencil = d3d9::GetAttachmentRenderTarget(drawBuffer);
-        }
+        // The getSurface calls do an AddRef so save them until after no errors are possible
+        IDirect3DSurface9* readSurface = readDepthStencil->getSurface();
+        ASSERT(readDepthStencil);
 
-        if (readDepthStencil)
-        {
-            readSurface = readDepthStencil->getSurface();
-        }
-        if (drawDepthStencil)
-        {
-            drawSurface = drawDepthStencil->getSurface();
-        }
-
-        if (!readSurface || !drawSurface)
-        {
-            return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the internal render targets for the blit framebuffers.");
-        }
+        IDirect3DSurface9* drawSurface = drawDepthStencil->getSurface();
+        ASSERT(drawDepthStencil);
 
         HRESULT result = mDevice->StretchRect(readSurface, NULL, drawSurface, NULL, D3DTEXF_NONE);
 
@@ -2622,25 +2613,19 @@
 {
     ASSERT(pack.pixelBuffer.get() == NULL);
 
-    RenderTarget9 *renderTarget = NULL;
-    IDirect3DSurface9 *surface = NULL;
     gl::FramebufferAttachment *colorbuffer = framebuffer->getColorbuffer(0);
+    ASSERT(colorbuffer);
 
-    if (colorbuffer)
+    RenderTarget9 *renderTarget = NULL;
+    gl::Error error = d3d9::GetAttachmentRenderTarget(colorbuffer, &renderTarget);
+    if (error.isError())
     {
-        renderTarget = d3d9::GetAttachmentRenderTarget(colorbuffer);
+        return error;
     }
+    ASSERT(renderTarget);
 
-    if (renderTarget)
-    {
-        surface = renderTarget->getSurface();
-    }
-
-    if (!surface)
-    {
-        // context must be lost
-        return gl::Error(GL_NO_ERROR);
-    }
+    IDirect3DSurface9 *surface = renderTarget->getSurface();
+    ASSERT(surface);
 
     D3DSURFACE_DESC desc;
     surface->GetDesc(&desc);
diff --git a/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp b/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp
index cec3844..e721fdb 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp
@@ -166,9 +166,11 @@
     return surface;
 }
 
-RenderTarget *TextureStorage9_2D::getRenderTarget(const gl::ImageIndex &/*index*/)
+gl::Error TextureStorage9_2D::getRenderTarget(const gl::ImageIndex &/*index*/, RenderTarget **outRT)
 {
-    return mRenderTarget;
+    ASSERT(outRT);
+    *outRT = mRenderTarget;
+    return gl::Error(GL_NO_ERROR);
 }
 
 void TextureStorage9_2D::generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex)
@@ -299,9 +301,13 @@
     return surface;
 }
 
-RenderTarget *TextureStorage9_Cube::getRenderTarget(const gl::ImageIndex &index)
+gl::Error TextureStorage9_Cube::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
 {
-    return mRenderTarget[index.layerIndex];
+    ASSERT(outRT);
+    ASSERT(index.mipIndex == 0);
+    ASSERT(index.layerIndex >= 0 && index.layerIndex < 6);
+    *outRT = mRenderTarget[index.layerIndex];
+    return gl::Error(GL_NO_ERROR);
 }
 
 void TextureStorage9_Cube::generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex)
diff --git a/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.h b/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.h
index 7ce0390..fdeda00 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.h
+++ b/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.h
@@ -34,7 +34,7 @@
     DWORD getUsage() const;
 
     virtual IDirect3DBaseTexture9 *getBaseTexture() const = 0;
-    virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index) = 0;
+    virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) = 0;
     virtual void generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex) = 0;
 
     virtual int getTopLevel() const;
@@ -68,7 +68,7 @@
     static TextureStorage9_2D *makeTextureStorage9_2D(TextureStorage *storage);
 
     IDirect3DSurface9 *getSurfaceLevel(int level, bool dirty);
-    virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
+    virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
     virtual IDirect3DBaseTexture9 *getBaseTexture() const;
     virtual void generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex);
     virtual gl::Error copyToStorage(TextureStorage *destStorage);
@@ -91,7 +91,7 @@
     static TextureStorage9_Cube *makeTextureStorage9_Cube(TextureStorage *storage);
 
     IDirect3DSurface9 *getCubeMapSurface(GLenum faceTarget, int level, bool dirty);
-    virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
+    virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
     virtual IDirect3DBaseTexture9 *getBaseTexture() const;
     virtual void generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex);
     virtual gl::Error copyToStorage(TextureStorage *destStorage);
diff --git a/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp b/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp
index 5107974..a98b208 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp
@@ -533,10 +533,16 @@
     *levelOffset = upsampleCount;
 }
 
-RenderTarget9 *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment)
+gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget9 **outRT)
 {
-    RenderTarget *renderTarget = rx::GetAttachmentRenderTarget(attachment);
-    return RenderTarget9::makeRenderTarget9(renderTarget);
+    RenderTarget *renderTarget = NULL;
+    gl::Error error = rx::GetAttachmentRenderTarget(attachment, &renderTarget);
+    if (error.isError())
+    {
+        return error;
+    }
+    *outRT = RenderTarget9::makeRenderTarget9(renderTarget);
+    return gl::Error(GL_NO_ERROR);
 }
 
 Workarounds GenerateWorkarounds()
diff --git a/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.h b/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.h
index ce591d8..9760b97 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.h
+++ b/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.h
@@ -12,6 +12,7 @@
 
 #include "libGLESv2/angletypes.h"
 #include "libGLESv2/Caps.h"
+#include "libGLESv2/Error.h"
 
 namespace gl
 {
@@ -75,7 +76,7 @@
     }
 }
 
-RenderTarget9 *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment);
+gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget9 **outRT);
 Workarounds GenerateWorkarounds();
 
 }