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 ...@@ -526,6 +526,16 @@ namespace egl
default: UNREACHABLE(type); default: UNREACHABLE(type);
} }
break; 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: default:
UNREACHABLE(format); UNREACHABLE(format);
} }
......
...@@ -257,13 +257,14 @@ namespace gl ...@@ -257,13 +257,14 @@ namespace gl
return sizeof(unsigned short); return sizeof(unsigned short);
case GL_UNSIGNED_INT: case GL_UNSIGNED_INT:
case GL_UNSIGNED_INT_24_8_EXT: 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); return sizeof(unsigned int);
case GL_FLOAT: case GL_FLOAT:
switch(format) switch(format)
{ {
case GL_ALPHA: return sizeof(float); case GL_ALPHA: return sizeof(float);
case GL_LUMINANCE: 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_LUMINANCE_ALPHA: return sizeof(float) * 2;
case GL_RGB: return sizeof(float) * 3; case GL_RGB: return sizeof(float) * 3;
case GL_RGBA: return sizeof(float) * 4; case GL_RGBA: return sizeof(float) * 4;
......
...@@ -3210,24 +3210,34 @@ void Context::applyTexture(sw::SamplerType type, int index, Texture *baseTexture ...@@ -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, void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
{ {
Framebuffer *framebuffer = getReadFramebuffer(); Framebuffer *framebuffer = getReadFramebuffer();
int framebufferWidth, framebufferHeight, framebufferSamples; int framebufferWidth, framebufferHeight, framebufferSamples;
if(framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE) if(framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE)
{ {
return error(GL_INVALID_FRAMEBUFFER_OPERATION); return error(GL_INVALID_FRAMEBUFFER_OPERATION);
} }
if(getReadFramebufferName() != 0 && framebufferSamples != 0) if(getReadFramebufferName() != 0 && framebufferSamples != 0)
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
GLenum readFormat = framebuffer->getImplementationColorReadFormat(); GLenum readFormat = GL_NONE;
GLenum readType = framebuffer->getImplementationColorReadType(); 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)) 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, ...@@ -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); pixels = ((char*)pixels) + egl::ComputePackingOffset(format, type, outputWidth, outputHeight, mState.packAlignment, mState.packSkipImages, mState.packSkipRows, mState.packSkipPixels);
// Sized query sanity check // Sized query sanity check
if(bufSize) if(bufSize)
{ {
int requiredSize = outputPitch * height; int requiredSize = outputPitch * height;
if(requiredSize > *bufSize) if(requiredSize > *bufSize)
{ {
return error(GL_INVALID_OPERATION); 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) if(!renderTarget)
{ {
return error(GL_OUT_OF_MEMORY); return error(GL_INVALID_OPERATION);
} }
sw::Rect rect = {x, y, x + width, y + height}; sw::Rect rect = {x, y, x + width, y + height};
sw::Rect dstRect = { 0, 0, width, height }; sw::Rect dstRect = { 0, 0, width, height };
...@@ -4269,6 +4288,7 @@ const GLubyte* Context::getExtensions(GLuint index, GLuint* numExt) const ...@@ -4269,6 +4288,7 @@ const GLubyte* Context::getExtensions(GLuint index, GLuint* numExt) const
(const GLubyte*)"GL_ANGLE_texture_compression_dxt5", (const GLubyte*)"GL_ANGLE_texture_compression_dxt5",
#endif #endif
(const GLubyte*)"GL_NV_fence", (const GLubyte*)"GL_NV_fence",
(const GLubyte*)"GL_NV_read_depth",
(const GLubyte*)"GL_EXT_instanced_arrays", (const GLubyte*)"GL_EXT_instanced_arrays",
(const GLubyte*)"GL_ANGLE_instanced_arrays", (const GLubyte*)"GL_ANGLE_instanced_arrays",
}; };
......
...@@ -602,6 +602,45 @@ GLenum Framebuffer::getImplementationColorReadType() ...@@ -602,6 +602,45 @@ GLenum Framebuffer::getImplementationColorReadType()
return GL_UNSIGNED_BYTE; 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) DefaultFramebuffer::DefaultFramebuffer(Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil)
{ {
GLenum defaultRenderbufferType = egl::getClientVersion() < 3 ? GL_RENDERBUFFER : GL_FRAMEBUFFER_DEFAULT; GLenum defaultRenderbufferType = egl::getClientVersion() < 3 ? GL_RENDERBUFFER : GL_FRAMEBUFFER_DEFAULT;
......
...@@ -32,76 +32,78 @@ class DepthStencilbuffer; ...@@ -32,76 +32,78 @@ class DepthStencilbuffer;
class Framebuffer class Framebuffer
{ {
public: public:
Framebuffer(); Framebuffer();
virtual ~Framebuffer(); virtual ~Framebuffer();
void setColorbuffer(GLenum type, GLuint colorbuffer, GLuint index, 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 setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level = 0, GLint layer = 0);
void setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level = 0, GLint layer = 0); void setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level = 0, GLint layer = 0);
void setReadBuffer(GLenum buf); void setReadBuffer(GLenum buf);
void setDrawBuffer(GLuint index, GLenum buf); void setDrawBuffer(GLuint index, GLenum buf);
GLenum getReadBuffer() const; GLenum getReadBuffer() const;
GLenum getDrawBuffer(GLuint index) const; GLenum getDrawBuffer(GLuint index) const;
void detachTexture(GLuint texture); void detachTexture(GLuint texture);
void detachRenderbuffer(GLuint renderbuffer); void detachRenderbuffer(GLuint renderbuffer);
egl::Image *getRenderTarget(GLuint index); egl::Image *getRenderTarget(GLuint index);
egl::Image *getReadRenderTarget(); egl::Image *getReadRenderTarget();
egl::Image *getDepthBuffer(); egl::Image *getDepthBuffer();
egl::Image *getStencilBuffer(); egl::Image *getStencilBuffer();
Renderbuffer *getColorbuffer(GLuint index); Renderbuffer *getColorbuffer(GLuint index);
Renderbuffer *getReadColorbuffer(); Renderbuffer *getReadColorbuffer();
Renderbuffer *getDepthbuffer(); Renderbuffer *getDepthbuffer();
Renderbuffer *getStencilbuffer(); Renderbuffer *getStencilbuffer();
GLenum getColorbufferType(GLuint index); GLenum getColorbufferType(GLuint index);
GLenum getDepthbufferType(); GLenum getDepthbufferType();
GLenum getStencilbufferType(); GLenum getStencilbufferType();
GLuint getColorbufferName(GLuint index); GLuint getColorbufferName(GLuint index);
GLuint getDepthbufferName(); GLuint getDepthbufferName();
GLuint getStencilbufferName(); GLuint getStencilbufferName();
GLint getColorbufferLayer(GLuint index); GLint getColorbufferLayer(GLuint index);
GLint getDepthbufferLayer(); GLint getDepthbufferLayer();
GLint getStencilbufferLayer(); GLint getStencilbufferLayer();
bool hasStencil(); bool hasStencil();
GLenum completeness(); GLenum completeness();
GLenum completeness(int &width, int &height, int &samples); GLenum completeness(int &width, int &height, int &samples);
GLenum getImplementationColorReadFormat(); GLenum getImplementationColorReadFormat();
GLenum getImplementationColorReadType(); GLenum getImplementationColorReadType();
GLenum getDepthReadFormat();
GLenum getDepthReadType();
virtual bool isDefaultFramebuffer() const { return false; } virtual bool isDefaultFramebuffer() const { return false; }
static bool IsRenderbuffer(GLenum type); static bool IsRenderbuffer(GLenum type);
protected: protected:
GLenum mColorbufferType[MAX_COLOR_ATTACHMENTS]; GLenum mColorbufferType[MAX_COLOR_ATTACHMENTS];
gl::BindingPointer<Renderbuffer> mColorbufferPointer[MAX_COLOR_ATTACHMENTS]; gl::BindingPointer<Renderbuffer> mColorbufferPointer[MAX_COLOR_ATTACHMENTS];
GLenum readBuffer; GLenum readBuffer;
GLenum drawBuffer[MAX_COLOR_ATTACHMENTS]; GLenum drawBuffer[MAX_COLOR_ATTACHMENTS];
GLenum mDepthbufferType; GLenum mDepthbufferType;
gl::BindingPointer<Renderbuffer> mDepthbufferPointer; gl::BindingPointer<Renderbuffer> mDepthbufferPointer;
GLenum mStencilbufferType; GLenum mStencilbufferType;
gl::BindingPointer<Renderbuffer> mStencilbufferPointer; gl::BindingPointer<Renderbuffer> mStencilbufferPointer;
private: 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 class DefaultFramebuffer : public Framebuffer
{ {
public: public:
DefaultFramebuffer(Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil); DefaultFramebuffer(Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil);
bool isDefaultFramebuffer() const override { return true; } bool isDefaultFramebuffer() const override { return true; }
}; };
......
...@@ -632,12 +632,6 @@ bool DepthStencilbuffer::isShared() const ...@@ -632,12 +632,6 @@ bool DepthStencilbuffer::isShared() const
Depthbuffer::Depthbuffer(egl::Image *depthStencil) : DepthStencilbuffer(depthStencil) 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) Depthbuffer::Depthbuffer(int width, int height, GLenum format, GLsizei samples) : DepthStencilbuffer(width, height, format, samples)
...@@ -650,12 +644,6 @@ Depthbuffer::~Depthbuffer() ...@@ -650,12 +644,6 @@ Depthbuffer::~Depthbuffer()
Stencilbuffer::Stencilbuffer(egl::Image *depthStencil) : DepthStencilbuffer(depthStencil) 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) Stencilbuffer::Stencilbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, GL_STENCIL_INDEX8, samples)
......
...@@ -652,6 +652,24 @@ namespace es2 ...@@ -652,6 +652,24 @@ namespace es2
case GL_RG_EXT: case GL_RG_EXT:
case GL_RED_EXT: case GL_RED_EXT:
return (clientVersion >= 3) && (type == GL_UNSIGNED_BYTE); 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: default:
return false; return false;
} }
......
...@@ -292,6 +292,30 @@ namespace sw ...@@ -292,6 +292,30 @@ namespace sw
c.z = Float(Int((*Pointer<UInt>(element) & UInt(0x3FF00000)) >> 20)); c.z = Float(Int((*Pointer<UInt>(element) & UInt(0x3FF00000)) >> 20));
c.w = Float(Int((*Pointer<UInt>(element) & UInt(0xC0000000)) >> 30)); c.w = Float(Int((*Pointer<UInt>(element) & UInt(0xC0000000)) >> 30));
break; 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: default:
return false; return false;
} }
...@@ -634,6 +658,30 @@ namespace sw ...@@ -634,6 +658,30 @@ namespace sw
(RoundInt(Float(c.w)) << 30)) & UInt(mask)); (RoundInt(Float(c.w)) << 30)) & UInt(mask));
} }
break; 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: default:
return false; return false;
} }
...@@ -925,6 +973,22 @@ namespace sw ...@@ -925,6 +973,22 @@ namespace sw
case FORMAT_A2B10G10R10: case FORMAT_A2B10G10R10:
scale = vector(0x3FF, 0x3FF, 0x3FF, 0x03); scale = vector(0x3FF, 0x3FF, 0x3FF, 0x03);
break; 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: default:
return false; 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