Added Renderbuffers for 3D and 2DArray textures.

TRAC #23470

Signed-off-by: Jamie Madill
Signed-off-by: Shannon Woods
Author: Geoff Lang
diff --git a/src/libGLESv2/Renderbuffer.cpp b/src/libGLESv2/Renderbuffer.cpp
index 940e3b3..837d617 100644
--- a/src/libGLESv2/Renderbuffer.cpp
+++ b/src/libGLESv2/Renderbuffer.cpp
@@ -165,6 +165,134 @@
     return mTextureCubeMap->getRenderTargetSerial(mFaceTarget, mLevel);
 }
 
+///// RenderbufferTexture3DLayer Implementation ////////
+
+RenderbufferTexture3DLayer::RenderbufferTexture3DLayer(Texture3D *texture, GLint level, GLint layer)
+    : mLevel(level), mLayer(layer)
+{
+    mTexture3D.set(texture);
+}
+
+RenderbufferTexture3DLayer::~RenderbufferTexture3DLayer()
+{
+    mTexture3D.set(NULL);
+}
+
+// Textures need to maintain their own reference count for references via
+// Renderbuffers acting as proxies. Here, we notify the texture of a reference.
+void RenderbufferTexture3DLayer::addProxyRef(const Renderbuffer *proxy)
+{
+    mTexture3D->addProxyRef(proxy);
+}
+
+void RenderbufferTexture3DLayer::releaseProxy(const Renderbuffer *proxy)
+{
+    mTexture3D->releaseProxy(proxy);
+}
+
+rx::RenderTarget *RenderbufferTexture3DLayer::getRenderTarget()
+{
+    return mTexture3D->getRenderTarget(mLevel, mLayer);
+}
+
+rx::RenderTarget *RenderbufferTexture3DLayer::getDepthStencil()
+{
+    return mTexture3D->getDepthStencil(mLevel, mLayer);
+}
+
+GLsizei RenderbufferTexture3DLayer::getWidth() const
+{
+    return mTexture3D->getWidth(mLevel);
+}
+
+GLsizei RenderbufferTexture3DLayer::getHeight() const
+{
+    return mTexture3D->getHeight(mLevel);
+}
+
+GLenum RenderbufferTexture3DLayer::getInternalFormat() const
+{
+    return mTexture3D->getInternalFormat(mLevel);
+}
+
+GLenum RenderbufferTexture3DLayer::getActualFormat() const
+{
+    return mTexture3D->getActualFormat(mLevel);
+}
+
+GLsizei RenderbufferTexture3DLayer::getSamples() const
+{
+    return 0;
+}
+
+unsigned int RenderbufferTexture3DLayer::getSerial() const
+{
+    return mTexture3D->getRenderTargetSerial(mLevel, mLayer);
+}
+
+////// RenderbufferTexture2DArrayLayer Implementation //////
+
+RenderbufferTexture2DArrayLayer::RenderbufferTexture2DArrayLayer(Texture2DArray *texture, GLint level, GLint layer)
+    : mLevel(level), mLayer(layer)
+{
+    mTexture2DArray.set(texture);
+}
+
+RenderbufferTexture2DArrayLayer::~RenderbufferTexture2DArrayLayer()
+{
+    mTexture2DArray.set(NULL);
+}
+
+void RenderbufferTexture2DArrayLayer::addProxyRef(const Renderbuffer *proxy)
+{
+    mTexture2DArray->addProxyRef(proxy);
+}
+
+void RenderbufferTexture2DArrayLayer::releaseProxy(const Renderbuffer *proxy)
+{
+    mTexture2DArray->releaseProxy(proxy);
+}
+
+rx::RenderTarget *RenderbufferTexture2DArrayLayer::getRenderTarget()
+{
+    return mTexture2DArray->getRenderTarget(mLevel, mLayer);
+}
+
+rx::RenderTarget *RenderbufferTexture2DArrayLayer::getDepthStencil()
+{
+    return mTexture2DArray->getDepthStencil(mLevel, mLayer);
+}
+
+GLsizei RenderbufferTexture2DArrayLayer::getWidth() const
+{
+    return mTexture2DArray->getWidth(mLevel);
+}
+
+GLsizei RenderbufferTexture2DArrayLayer::getHeight() const
+{
+    return mTexture2DArray->getHeight(mLevel);
+}
+
+GLenum RenderbufferTexture2DArrayLayer::getInternalFormat() const
+{
+    return mTexture2DArray->getInternalFormat(mLevel);
+}
+
+GLenum RenderbufferTexture2DArrayLayer::getActualFormat() const
+{
+    return mTexture2DArray->getActualFormat(mLevel);
+}
+
+GLsizei RenderbufferTexture2DArrayLayer::getSamples() const
+{
+    return 0;
+}
+
+unsigned int RenderbufferTexture2DArrayLayer::getSerial() const
+{
+    return mTexture2DArray->getRenderTargetSerial(mLevel, mLayer);
+}
+
 ////// Renderbuffer Implementation //////
 
 Renderbuffer::Renderbuffer(rx::Renderer *renderer, GLuint id, RenderbufferInterface *instance) : RefCountObject(id)
diff --git a/src/libGLESv2/Renderbuffer.h b/src/libGLESv2/Renderbuffer.h
index 103be97..1d359a8 100644
--- a/src/libGLESv2/Renderbuffer.h
+++ b/src/libGLESv2/Renderbuffer.h
@@ -30,6 +30,8 @@
 {
 class Texture2D;
 class TextureCubeMap;
+class Texture3D;
+class Texture2DArray;
 class Renderbuffer;
 class Colorbuffer;
 class DepthStencilbuffer;
@@ -116,6 +118,64 @@
     const GLenum mFaceTarget;
 };
 
+class RenderbufferTexture3DLayer : public RenderbufferInterface
+{
+public:
+    RenderbufferTexture3DLayer(Texture3D *texture, GLint level, GLint layer);
+
+    virtual ~RenderbufferTexture3DLayer();
+
+    void addProxyRef(const Renderbuffer *proxy);
+    void releaseProxy(const Renderbuffer *proxy);
+
+    rx::RenderTarget *getRenderTarget();
+    rx::RenderTarget *getDepthStencil();
+
+    virtual GLsizei getWidth() const;
+    virtual GLsizei getHeight() const;
+    virtual GLenum getInternalFormat() const;
+    virtual GLenum getActualFormat() const;
+    virtual GLsizei getSamples() const;
+
+    virtual unsigned int getSerial() const;
+
+private:
+    DISALLOW_COPY_AND_ASSIGN(RenderbufferTexture3DLayer);
+
+    BindingPointer<Texture3D> mTexture3D;
+    const GLint mLevel;
+    const GLint mLayer;
+};
+
+class RenderbufferTexture2DArrayLayer : public RenderbufferInterface
+{
+public:
+    RenderbufferTexture2DArrayLayer(Texture2DArray *texture, GLint level, GLint layer);
+
+    virtual ~RenderbufferTexture2DArrayLayer();
+
+    void addProxyRef(const Renderbuffer *proxy);
+    void releaseProxy(const Renderbuffer *proxy);
+
+    rx::RenderTarget *getRenderTarget();
+    rx::RenderTarget *getDepthStencil();
+
+    virtual GLsizei getWidth() const;
+    virtual GLsizei getHeight() const;
+    virtual GLenum getInternalFormat() const;
+    virtual GLenum getActualFormat() const;
+    virtual GLsizei getSamples() const;
+
+    virtual unsigned int getSerial() const;
+
+private:
+    DISALLOW_COPY_AND_ASSIGN(RenderbufferTexture2DArrayLayer);
+
+    BindingPointer<Texture2DArray> mTexture2DArray;
+    const GLint mLevel;
+    const GLint mLayer;
+};
+
 // A class derived from RenderbufferStorage is created whenever glRenderbufferStorage
 // is called. The specific concrete type depends on whether the internal format is
 // colour depth, stencil or packed depth/stencil.
diff --git a/src/libGLESv2/Texture.cpp b/src/libGLESv2/Texture.cpp
index 425dee9..cbcc7bf 100644
--- a/src/libGLESv2/Texture.cpp
+++ b/src/libGLESv2/Texture.cpp
@@ -1942,9 +1942,8 @@
     Renderbuffer *renderBuffer = mRenderbufferProxies.get(level, layer);
     if (!renderBuffer)
     {
-        UNIMPLEMENTED();
-        //renderBuffer = new Renderbuffer(mRenderer, id(), new RenderbufferTexture3DLayer(this, level, layer));
-        //mRenderbufferProxies.add(level, 0, renderBuffer);
+        renderBuffer = new Renderbuffer(mRenderer, id(), new RenderbufferTexture3DLayer(this, level, layer));
+        mRenderbufferProxies.add(level, 0, renderBuffer);
     }
 
     return renderBuffer;
@@ -2490,9 +2489,8 @@
     Renderbuffer *renderBuffer = mRenderbufferProxies.get(level, layer);
     if (!renderBuffer)
     {
-        UNIMPLEMENTED();
-        //renderBuffer = new Renderbuffer(mRenderer, id(), new RenderbufferTexture2DArrayLayer(this, level, layer));
-        //mRenderbufferProxies.add(level, 0, renderBuffer);
+        renderBuffer = new Renderbuffer(mRenderer, id(), new RenderbufferTexture2DArrayLayer(this, level, layer));
+        mRenderbufferProxies.add(level, 0, renderBuffer);
     }
 
     return renderBuffer;
diff --git a/src/libGLESv2/Texture.h b/src/libGLESv2/Texture.h
index ed7533e..dabd9d9 100644
--- a/src/libGLESv2/Texture.h
+++ b/src/libGLESv2/Texture.h
@@ -301,6 +301,7 @@
     unsigned int getRenderTargetSerial(GLint level, GLint layer);
 
   protected:
+    friend class RenderbufferTexture3DLayer;
     rx::RenderTarget *getRenderTarget(GLint level, GLint layer);
     rx::RenderTarget *getDepthStencil(GLint level, GLint layer);
     virtual int levelCount();
@@ -356,6 +357,7 @@
     unsigned int getRenderTargetSerial(GLint level, GLint layer);
 
   protected:
+    friend class RenderbufferTexture2DArrayLayer;
     rx::RenderTarget *getRenderTarget(GLint level, GLint layer);
     rx::RenderTarget *getDepthStencil(GLint level, GLint layer);
     virtual int levelCount();