Commit bc07bf6c by John Sheu

Add support for GL_NV_read_depth

Change-Id: If2f96b4cc1c09cd28771740f09be5f84875033ab Reviewed-on: https://swiftshader-review.googlesource.com/5091Reviewed-by: 's avatarNicolas Capens <capn@google.com> Tested-by: 's avatarNicolas Capens <capn@google.com>
parent c66f0e36
......@@ -526,6 +526,16 @@ namespace egl
default: UNREACHABLE(type);
}
break;
case GL_DEPTH_COMPONENT:
switch(type)
{
case GL_UNSIGNED_SHORT: return sw::FORMAT_D16;
case GL_UNSIGNED_INT_24_8_OES: return sw::FORMAT_D24S8;
case GL_UNSIGNED_INT: return sw::FORMAT_D32;
case GL_FLOAT: return sw::FORMAT_D32F;
default: UNREACHABLE(type);
}
break;
default:
UNREACHABLE(format);
}
......
......@@ -257,13 +257,14 @@ namespace gl
return sizeof(unsigned short);
case GL_UNSIGNED_INT:
case GL_UNSIGNED_INT_24_8_EXT:
case GL_UNSIGNED_INT_8_8_8_8_REV:
case GL_UNSIGNED_INT_8_8_8_8_REV:
return sizeof(unsigned int);
case GL_FLOAT:
switch(format)
{
case GL_ALPHA: return sizeof(float);
case GL_LUMINANCE: return sizeof(float);
case GL_DEPTH_COMPONENT: return sizeof(float);
case GL_LUMINANCE_ALPHA: return sizeof(float) * 2;
case GL_RGB: return sizeof(float) * 3;
case GL_RGBA: return sizeof(float) * 4;
......
......@@ -3210,24 +3210,34 @@ void Context::applyTexture(sw::SamplerType type, int index, Texture *baseTexture
}
}
void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
{
Framebuffer *framebuffer = getReadFramebuffer();
Framebuffer *framebuffer = getReadFramebuffer();
int framebufferWidth, framebufferHeight, framebufferSamples;
if(framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE)
{
return error(GL_INVALID_FRAMEBUFFER_OPERATION);
}
if(framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE)
{
return error(GL_INVALID_FRAMEBUFFER_OPERATION);
}
if(getReadFramebufferName() != 0 && framebufferSamples != 0)
{
return error(GL_INVALID_OPERATION);
}
if(getReadFramebufferName() != 0 && framebufferSamples != 0)
{
return error(GL_INVALID_OPERATION);
}
GLenum readFormat = framebuffer->getImplementationColorReadFormat();
GLenum readType = framebuffer->getImplementationColorReadType();
GLenum readFormat = GL_NONE;
GLenum readType = GL_NONE;
switch(format)
{
case GL_DEPTH_COMPONENT:
readFormat = framebuffer->getDepthReadFormat();
readType = framebuffer->getDepthReadType();
break;
default:
readFormat = framebuffer->getImplementationColorReadFormat();
readType = framebuffer->getImplementationColorReadType();
break;
}
if(!(readFormat == format && readType == type) && !ValidReadPixelsFormatType(readFormat, readType, format, type, clientVersion))
{
......@@ -3241,21 +3251,30 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
pixels = ((char*)pixels) + egl::ComputePackingOffset(format, type, outputWidth, outputHeight, mState.packAlignment, mState.packSkipImages, mState.packSkipRows, mState.packSkipPixels);
// Sized query sanity check
if(bufSize)
{
int requiredSize = outputPitch * height;
if(requiredSize > *bufSize)
{
return error(GL_INVALID_OPERATION);
}
}
if(bufSize)
{
int requiredSize = outputPitch * height;
if(requiredSize > *bufSize)
{
return error(GL_INVALID_OPERATION);
}
}
egl::Image *renderTarget = framebuffer->getReadRenderTarget();
egl::Image *renderTarget = nullptr;
switch(format)
{
case GL_DEPTH_COMPONENT:
renderTarget = framebuffer->getDepthBuffer();
break;
default:
renderTarget = framebuffer->getReadRenderTarget();
break;
}
if(!renderTarget)
{
return error(GL_OUT_OF_MEMORY);
}
if(!renderTarget)
{
return error(GL_INVALID_OPERATION);
}
sw::Rect rect = {x, y, x + width, y + height};
sw::Rect dstRect = { 0, 0, width, height };
......@@ -4269,6 +4288,7 @@ const GLubyte* Context::getExtensions(GLuint index, GLuint* numExt) const
(const GLubyte*)"GL_ANGLE_texture_compression_dxt5",
#endif
(const GLubyte*)"GL_NV_fence",
(const GLubyte*)"GL_NV_read_depth",
(const GLubyte*)"GL_EXT_instanced_arrays",
(const GLubyte*)"GL_ANGLE_instanced_arrays",
};
......
......@@ -602,6 +602,45 @@ GLenum Framebuffer::getImplementationColorReadType()
return GL_UNSIGNED_BYTE;
}
GLenum Framebuffer::getDepthReadFormat()
{
Renderbuffer *depthbuffer = getDepthbuffer();
if (depthbuffer)
{
// There is only one depth read format.
return GL_DEPTH_COMPONENT;
}
// If there is no depth buffer, GL_INVALID_OPERATION occurs.
return GL_NONE;
}
GLenum Framebuffer::getDepthReadType()
{
Renderbuffer *depthbuffer = getDepthbuffer();
if (depthbuffer)
{
switch (depthbuffer->getInternalFormat())
{
case sw::FORMAT_D16: return GL_UNSIGNED_SHORT;
case sw::FORMAT_D24S8: return GL_UNSIGNED_INT_24_8_OES;
case sw::FORMAT_D32: return GL_UNSIGNED_INT;
case sw::FORMAT_D32F:
case sw::FORMAT_D32F_COMPLEMENTARY:
case sw::FORMAT_D32F_LOCKABLE:
case sw::FORMAT_D32FS8_TEXTURE:
case sw::FORMAT_D32FS8_SHADOW: return GL_FLOAT;
default:
UNREACHABLE(depthbuffer->getInternalFormat());
}
}
// If there is no depth buffer, GL_INVALID_OPERATION occurs.
return GL_NONE;
}
DefaultFramebuffer::DefaultFramebuffer(Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil)
{
GLenum defaultRenderbufferType = egl::getClientVersion() < 3 ? GL_RENDERBUFFER : GL_FRAMEBUFFER_DEFAULT;
......
......@@ -32,76 +32,78 @@ class DepthStencilbuffer;
class Framebuffer
{
public:
Framebuffer();
Framebuffer();
virtual ~Framebuffer();
virtual ~Framebuffer();
void setColorbuffer(GLenum type, GLuint colorbuffer, GLuint index, GLint level = 0, GLint layer = 0);
void setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level = 0, GLint layer = 0);
void setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level = 0, GLint layer = 0);
void setColorbuffer(GLenum type, GLuint colorbuffer, GLuint index, GLint level = 0, GLint layer = 0);
void setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level = 0, GLint layer = 0);
void setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level = 0, GLint layer = 0);
void setReadBuffer(GLenum buf);
void setDrawBuffer(GLuint index, GLenum buf);
GLenum getReadBuffer() const;
GLenum getDrawBuffer(GLuint index) const;
void detachTexture(GLuint texture);
void detachRenderbuffer(GLuint renderbuffer);
void detachTexture(GLuint texture);
void detachRenderbuffer(GLuint renderbuffer);
egl::Image *getRenderTarget(GLuint index);
egl::Image *getReadRenderTarget();
egl::Image *getRenderTarget(GLuint index);
egl::Image *getReadRenderTarget();
egl::Image *getDepthBuffer();
egl::Image *getStencilBuffer();
Renderbuffer *getColorbuffer(GLuint index);
Renderbuffer *getReadColorbuffer();
Renderbuffer *getDepthbuffer();
Renderbuffer *getStencilbuffer();
Renderbuffer *getColorbuffer(GLuint index);
Renderbuffer *getReadColorbuffer();
Renderbuffer *getDepthbuffer();
Renderbuffer *getStencilbuffer();
GLenum getColorbufferType(GLuint index);
GLenum getDepthbufferType();
GLenum getStencilbufferType();
GLenum getColorbufferType(GLuint index);
GLenum getDepthbufferType();
GLenum getStencilbufferType();
GLuint getColorbufferName(GLuint index);
GLuint getDepthbufferName();
GLuint getStencilbufferName();
GLuint getColorbufferName(GLuint index);
GLuint getDepthbufferName();
GLuint getStencilbufferName();
GLint getColorbufferLayer(GLuint index);
GLint getDepthbufferLayer();
GLint getStencilbufferLayer();
bool hasStencil();
bool hasStencil();
GLenum completeness();
GLenum completeness(int &width, int &height, int &samples);
GLenum getImplementationColorReadFormat();
GLenum getImplementationColorReadType();
GLenum getDepthReadFormat();
GLenum getDepthReadType();
virtual bool isDefaultFramebuffer() const { return false; }
static bool IsRenderbuffer(GLenum type);
protected:
GLenum mColorbufferType[MAX_COLOR_ATTACHMENTS];
gl::BindingPointer<Renderbuffer> mColorbufferPointer[MAX_COLOR_ATTACHMENTS];
GLenum mColorbufferType[MAX_COLOR_ATTACHMENTS];
gl::BindingPointer<Renderbuffer> mColorbufferPointer[MAX_COLOR_ATTACHMENTS];
GLenum readBuffer;
GLenum drawBuffer[MAX_COLOR_ATTACHMENTS];
GLenum mDepthbufferType;
gl::BindingPointer<Renderbuffer> mDepthbufferPointer;
GLenum mDepthbufferType;
gl::BindingPointer<Renderbuffer> mDepthbufferPointer;
GLenum mStencilbufferType;
gl::BindingPointer<Renderbuffer> mStencilbufferPointer;
GLenum mStencilbufferType;
gl::BindingPointer<Renderbuffer> mStencilbufferPointer;
private:
Renderbuffer *lookupRenderbuffer(GLenum type, GLuint handle, GLint level, GLint layer) const;
Renderbuffer *lookupRenderbuffer(GLenum type, GLuint handle, GLint level, GLint layer) const;
};
class DefaultFramebuffer : public Framebuffer
{
public:
DefaultFramebuffer(Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil);
DefaultFramebuffer(Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil);
bool isDefaultFramebuffer() const override { return true; }
};
......
......@@ -632,12 +632,6 @@ bool DepthStencilbuffer::isShared() const
Depthbuffer::Depthbuffer(egl::Image *depthStencil) : DepthStencilbuffer(depthStencil)
{
if(depthStencil)
{
format = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function
// will expect one of the valid renderbuffer formats for use in
// glRenderbufferStorage
}
}
Depthbuffer::Depthbuffer(int width, int height, GLenum format, GLsizei samples) : DepthStencilbuffer(width, height, format, samples)
......@@ -650,12 +644,6 @@ Depthbuffer::~Depthbuffer()
Stencilbuffer::Stencilbuffer(egl::Image *depthStencil) : DepthStencilbuffer(depthStencil)
{
if(depthStencil)
{
format = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function
// will expect one of the valid renderbuffer formats for use in
// glRenderbufferStorage
}
}
Stencilbuffer::Stencilbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, GL_STENCIL_INDEX8, samples)
......
......@@ -652,6 +652,24 @@ namespace es2
case GL_RG_EXT:
case GL_RED_EXT:
return (clientVersion >= 3) && (type == GL_UNSIGNED_BYTE);
case GL_DEPTH_COMPONENT:
if (internalFormat != format)
{
return false;
}
switch(type)
{
case GL_UNSIGNED_SHORT:
case GL_FLOAT:
if (internalType != type)
{
return false;
}
break;
default:
return false;
}
break;
default:
return false;
}
......
......@@ -292,6 +292,30 @@ namespace sw
c.z = Float(Int((*Pointer<UInt>(element) & UInt(0x3FF00000)) >> 20));
c.w = Float(Int((*Pointer<UInt>(element) & UInt(0xC0000000)) >> 30));
break;
case FORMAT_D16:
c.x = Float(Int((*Pointer<UShort>(element))));
break;
case FORMAT_D24S8:
c.x = Float(Int((*Pointer<UInt>(element))));
break;
case FORMAT_D32:
c.x = Float(Int((*Pointer<UInt>(element))));
break;
case FORMAT_D32F:
c.x = *Pointer<Float>(element);
break;
case FORMAT_D32F_COMPLEMENTARY:
c.x = 1.0f - *Pointer<Float>(element);
break;
case FORMAT_D32F_LOCKABLE:
c.x = *Pointer<Float>(element);
break;
case FORMAT_D32FS8_TEXTURE:
c.x = *Pointer<Float>(element);
break;
case FORMAT_D32FS8_SHADOW:
c.x = *Pointer<Float>(element);
break;
default:
return false;
}
......@@ -634,6 +658,30 @@ namespace sw
(RoundInt(Float(c.w)) << 30)) & UInt(mask));
}
break;
case FORMAT_D16:
*Pointer<UShort>(element) = UShort(RoundInt(Float(c.x)));
break;
case FORMAT_D24S8:
*Pointer<UInt>(element) = UInt(RoundInt(Float(c.x)));
break;
case FORMAT_D32:
*Pointer<UInt>(element) = UInt(RoundInt(Float(c.x)));
break;
case FORMAT_D32F:
*Pointer<Float>(element) = c.x;
break;
case FORMAT_D32F_COMPLEMENTARY:
*Pointer<Float>(element) = 1.0f - c.x;
break;
case FORMAT_D32F_LOCKABLE:
*Pointer<Float>(element) = c.x;
break;
case FORMAT_D32FS8_TEXTURE:
*Pointer<Float>(element) = c.x;
break;
case FORMAT_D32FS8_SHADOW:
*Pointer<Float>(element) = c.x;
break;
default:
return false;
}
......@@ -925,6 +973,22 @@ namespace sw
case FORMAT_A2B10G10R10:
scale = vector(0x3FF, 0x3FF, 0x3FF, 0x03);
break;
case FORMAT_D16:
scale = vector(0xFFFF, 0.0f, 0.0f, 0.0f);
break;
case FORMAT_D24S8:
scale = vector(0xFFFFFF, 0.0f, 0.0f, 0.0f);
break;
case FORMAT_D32:
scale = vector(0xFFFFFFFF, 0.0f, 0.0f, 0.0f);
break;
case FORMAT_D32F:
case FORMAT_D32F_COMPLEMENTARY:
case FORMAT_D32F_LOCKABLE:
case FORMAT_D32FS8_TEXTURE:
case FORMAT_D32FS8_SHADOW:
scale = vector(1.0f, 0.0f, 0.0f, 0.0f);
break;
default:
return false;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment