Apply the depth texture correctly as the DepthStencil surface in applyRenderTarget
Trac #20875
Signed-off-by: Nicolas Capens
git-svn-id: https://angleproject.googlecode.com/svn/trunk@1115 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp
index b395130..3ad2cf8 100644
--- a/src/libGLESv2/Context.cpp
+++ b/src/libGLESv2/Context.cpp
@@ -1841,13 +1841,31 @@
return error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
}
+ // if there is no color attachment we must synthesize a NULL colorattachment
+ // to keep the D3D runtime happy. This should only be possible if depth texturing.
+ Renderbuffer *renderbufferObject = NULL;
+ if (framebufferObject->getColorbufferType() != GL_NONE)
+ {
+ renderbufferObject = framebufferObject->getColorbuffer();
+ }
+ else
+ {
+ renderbufferObject = framebufferObject->getNullColorbuffer();
+ }
+ if (!renderbufferObject)
+ {
+ ERR("unable to locate renderbuffer for FBO.");
+ return false;
+ }
+
bool renderTargetChanged = false;
- unsigned int renderTargetSerial = framebufferObject->getRenderTargetSerial();
+ unsigned int renderTargetSerial = renderbufferObject->getSerial();
if (renderTargetSerial != mAppliedRenderTargetSerial)
{
- IDirect3DSurface9 *renderTarget = framebufferObject->getRenderTarget();
+ IDirect3DSurface9 *renderTarget = renderbufferObject->getRenderTarget();
if (!renderTarget)
{
+ ERR("render target pointer unexpectedly null.");
return false; // Context must be lost
}
mDevice->SetRenderTarget(0, renderTarget);
@@ -1862,25 +1880,27 @@
unsigned int stencilbufferSerial = 0;
if (framebufferObject->getDepthbufferType() != GL_NONE)
{
- depthStencil = framebufferObject->getDepthbuffer()->getDepthStencil();
+ Renderbuffer *depthbuffer = framebufferObject->getDepthbuffer();
+ depthStencil = depthbuffer->getDepthStencil();
if (!depthStencil)
{
ERR("Depth stencil pointer unexpectedly null.");
return false;
}
- depthbufferSerial = framebufferObject->getDepthbuffer()->getSerial();
+ depthbufferSerial = depthbuffer->getSerial();
}
else if (framebufferObject->getStencilbufferType() != GL_NONE)
{
- depthStencil = framebufferObject->getStencilbuffer()->getDepthStencil();
+ Renderbuffer *stencilbuffer = framebufferObject->getStencilbuffer();
+ depthStencil = stencilbuffer->getDepthStencil();
if (!depthStencil)
{
ERR("Depth stencil pointer unexpectedly null.");
return false;
}
- stencilbufferSerial = framebufferObject->getStencilbuffer()->getSerial();
+ stencilbufferSerial = stencilbuffer->getSerial();
}
if (depthbufferSerial != mAppliedDepthbufferSerial ||
@@ -1900,7 +1920,7 @@
if (!mRenderTargetDescInitialized || renderTargetChanged)
{
- IDirect3DSurface9 *renderTarget = framebufferObject->getRenderTarget();
+ IDirect3DSurface9 *renderTarget = renderbufferObject->getRenderTarget();
if (!renderTarget)
{
return false; // Context must be lost
diff --git a/src/libGLESv2/Framebuffer.cpp b/src/libGLESv2/Framebuffer.cpp
index 1277c06..21972ac 100644
--- a/src/libGLESv2/Framebuffer.cpp
+++ b/src/libGLESv2/Framebuffer.cpp
@@ -29,6 +29,7 @@
mColorbufferPointer.set(NULL);
mDepthbufferPointer.set(NULL);
mStencilbufferPointer.set(NULL);
+ mNullColorbufferPointer.set(NULL);
}
Renderbuffer *Framebuffer::lookupRenderbuffer(GLenum type, GLuint handle) const
@@ -200,6 +201,30 @@
return mStencilbufferPointer.get();
}
+Renderbuffer *Framebuffer::getNullColorbuffer()
+{
+ Renderbuffer *nullbuffer = mNullColorbufferPointer.get();
+ Renderbuffer *depthbuffer = getDepthbuffer();
+
+ if (!depthbuffer)
+ {
+ ERR("Unexpected null depthbuffer for depth-only FBO.");
+ return NULL;
+ }
+
+ GLsizei width = depthbuffer->getWidth();
+ GLsizei height = depthbuffer->getHeight();
+
+ if (!nullbuffer ||
+ width != nullbuffer->getWidth() || height != nullbuffer->getHeight())
+ {
+ nullbuffer = new Renderbuffer(0, new Colorbuffer(width, height, GL_NONE, 0));
+ mNullColorbufferPointer.set(nullbuffer);
+ }
+
+ return nullbuffer;
+}
+
GLenum Framebuffer::getColorbufferType()
{
return mColorbufferType;
diff --git a/src/libGLESv2/Framebuffer.h b/src/libGLESv2/Framebuffer.h
index b73f9a0..14d9c2a 100644
--- a/src/libGLESv2/Framebuffer.h
+++ b/src/libGLESv2/Framebuffer.h
@@ -49,6 +49,7 @@
Renderbuffer *getColorbuffer();
Renderbuffer *getDepthbuffer();
Renderbuffer *getStencilbuffer();
+ Renderbuffer *getNullColorbuffer();
GLenum getColorbufferType();
GLenum getDepthbufferType();
@@ -73,6 +74,8 @@
GLenum mStencilbufferType;
BindingPointer<Renderbuffer> mStencilbufferPointer;
+ BindingPointer<Renderbuffer> mNullColorbufferPointer;
+
private:
DISALLOW_COPY_AND_ASSIGN(Framebuffer);
diff --git a/src/libGLESv2/Renderbuffer.cpp b/src/libGLESv2/Renderbuffer.cpp
index f5abd9d..4b911e8 100644
--- a/src/libGLESv2/Renderbuffer.cpp
+++ b/src/libGLESv2/Renderbuffer.cpp
@@ -98,7 +98,7 @@
// caller must Release() the returned surface
IDirect3DSurface9 *RenderbufferTexture2D::getDepthStencil()
{
- return NULL;
+ return mTexture2D->getDepthStencil(mTarget);
}
GLsizei RenderbufferTexture2D::getWidth() const
diff --git a/src/libGLESv2/Texture.cpp b/src/libGLESv2/Texture.cpp
index 683ccc5..1af08cb 100644
--- a/src/libGLESv2/Texture.cpp
+++ b/src/libGLESv2/Texture.cpp
@@ -2374,6 +2374,33 @@
updateTexture();
+ // ensure this is NOT a depth texture
+ if (isDepth(0))
+ {
+ return NULL;
+ }
+ return mTexStorage->getSurfaceLevel(0);
+}
+
+// Increments refcount on surface.
+// caller must Release() the returned surface
+IDirect3DSurface9 *Texture2D::getDepthStencil(GLenum target)
+{
+ ASSERT(target == GL_TEXTURE_2D);
+
+ // ensure the underlying texture is created
+ if (getStorage(true) == NULL)
+ {
+ return NULL;
+ }
+
+ updateTexture();
+
+ // ensure this is actually a depth texture
+ if (!isDepth(0))
+ {
+ return NULL;
+ }
return mTexStorage->getSurfaceLevel(0);
}
diff --git a/src/libGLESv2/Texture.h b/src/libGLESv2/Texture.h
index 12f102b..2e63131 100644
--- a/src/libGLESv2/Texture.h
+++ b/src/libGLESv2/Texture.h
@@ -306,6 +306,7 @@
protected:
friend class RenderbufferTexture2D;
virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
+ virtual IDirect3DSurface9 *getDepthStencil(GLenum target);
private:
DISALLOW_COPY_AND_ASSIGN(Texture2D);
diff --git a/src/libGLESv2/utilities.cpp b/src/libGLESv2/utilities.cpp
index 3b77cd8..d34c665 100644
--- a/src/libGLESv2/utilities.cpp
+++ b/src/libGLESv2/utilities.cpp
@@ -795,6 +795,7 @@
{
switch (format)
{
+ case GL_NONE: return D3DFMT_NULL;
case GL_RGBA4:
case GL_RGB5_A1:
case GL_RGBA8_OES: return D3DFMT_A8R8G8B8;