Commit c8f95e8a by Alexis Hetu Committed by Alexis Hétu

Floating point renderbuffer support

It is now possible to use floating point renderbuffers and read the data back from them. The changes include: - Modified glReadPixels so that it always uses the blitter to copy the data to the external buffer. - Added new types to both Framebuffer and some utility functions. - Added the new ValidReadPixelsFormatType function to validate the glReadPixels format/type combo, which had a bit more possibilities than the RGBA/UNSIGNED BYTE combo previously used. Change-Id: I1726ea57c4f7aa85bf0ffa7f323dc6a16abc34ff Reviewed-on: https://swiftshader-review.googlesource.com/4260Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <capn@google.com>
parent f14891d7
...@@ -397,8 +397,10 @@ struct State ...@@ -397,8 +397,10 @@ struct State
egl::Image::UnpackInfo unpackInfo; egl::Image::UnpackInfo unpackInfo;
GLint packAlignment; GLint packAlignment;
GLint packRowLength; GLint packRowLength;
GLint packImageHeight;
GLint packSkipPixels; GLint packSkipPixels;
GLint packSkipRows; GLint packSkipRows;
GLint packSkipImages;
}; };
class Context : public egl::Context class Context : public egl::Context
...@@ -511,8 +513,10 @@ public: ...@@ -511,8 +513,10 @@ public:
void setPackAlignment(GLint alignment); void setPackAlignment(GLint alignment);
void setPackRowLength(GLint rowLength); void setPackRowLength(GLint rowLength);
void setPackImageHeight(GLint imageHeight);
void setPackSkipPixels(GLint skipPixels); void setPackSkipPixels(GLint skipPixels);
void setPackSkipRows(GLint skipRows); void setPackSkipRows(GLint skipRows);
void setPackSkipImages(GLint skipImages);
// These create and destroy methods are merely pass-throughs to // These create and destroy methods are merely pass-throughs to
// ResourceManager, which owns these object types // ResourceManager, which owns these object types
......
...@@ -284,7 +284,7 @@ GLenum Framebuffer::completeness(int &width, int &height, int &samples) ...@@ -284,7 +284,7 @@ GLenum Framebuffer::completeness(int &width, int &height, int &samples)
if(mColorbufferType[i] == GL_RENDERBUFFER) if(mColorbufferType[i] == GL_RENDERBUFFER)
{ {
if(!es2::IsColorRenderable(colorbuffer->getFormat())) if(!es2::IsColorRenderable(colorbuffer->getFormat(), egl::getClientVersion()))
{ {
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
} }
...@@ -448,14 +448,49 @@ GLenum Framebuffer::getImplementationColorReadFormat() ...@@ -448,14 +448,49 @@ GLenum Framebuffer::getImplementationColorReadFormat()
// Don't return GL_RGBA since that's always supported. Provide a second option here. // Don't return GL_RGBA since that's always supported. Provide a second option here.
switch(colorbuffer->getInternalFormat()) switch(colorbuffer->getInternalFormat())
{ {
case sw::FORMAT_A16B16G16R16F: return GL_BGRA_EXT; case sw::FORMAT_A8B8G8R8I:
case sw::FORMAT_A32B32G32R32F: return GL_BGRA_EXT; case sw::FORMAT_A8B8G8R8UI:
case sw::FORMAT_A8R8G8B8: return GL_BGRA_EXT; case sw::FORMAT_A16B16G16R16I:
case sw::FORMAT_A8B8G8R8: return GL_BGRA_EXT; case sw::FORMAT_A16B16G16R16UI:
case sw::FORMAT_X8R8G8B8: return 0x80E0; // GL_BGR_EXT case sw::FORMAT_A32B32G32R32I:
case sw::FORMAT_X8B8G8R8: return 0x80E0; // GL_BGR_EXT case sw::FORMAT_A32B32G32R32UI:return GL_RGBA_INTEGER;
case sw::FORMAT_A2B10G10R10: return GL_RGB10_A2;
case sw::FORMAT_A8B8G8R8I_SNORM:
case sw::FORMAT_A16B16G16R16F:
case sw::FORMAT_A32B32G32R32F:
case sw::FORMAT_A8R8G8B8:
case sw::FORMAT_A8B8G8R8:
case sw::FORMAT_A1R5G5B5: return GL_BGRA_EXT; case sw::FORMAT_A1R5G5B5: return GL_BGRA_EXT;
case sw::FORMAT_X8B8G8R8I:
case sw::FORMAT_X8B8G8R8UI:
case sw::FORMAT_X16B16G16R16I:
case sw::FORMAT_X16B16G16R16UI:
case sw::FORMAT_X32B32G32R32I:
case sw::FORMAT_X32B32G32R32UI:return GL_RGB_INTEGER;
case sw::FORMAT_X8B8G8R8I_SNORM:
case sw::FORMAT_X8B8G8R8:
case sw::FORMAT_X8R8G8B8:
case sw::FORMAT_R5G6B5: return 0x80E0; // GL_BGR_EXT case sw::FORMAT_R5G6B5: return 0x80E0; // GL_BGR_EXT
case sw::FORMAT_G8R8I:
case sw::FORMAT_G8R8UI:
case sw::FORMAT_G16R16I:
case sw::FORMAT_G16R16UI:
case sw::FORMAT_G32R32I:
case sw::FORMAT_G32R32UI: return GL_RG_INTEGER;
case sw::FORMAT_G8R8:
case sw::FORMAT_G8R8I_SNORM:
case sw::FORMAT_G16R16F:
case sw::FORMAT_G32R32F: return GL_RG;
case sw::FORMAT_R8I:
case sw::FORMAT_R8UI:
case sw::FORMAT_R16I:
case sw::FORMAT_R16UI:
case sw::FORMAT_R32I:
case sw::FORMAT_R32UI: return GL_RED_INTEGER;
case sw::FORMAT_R8:
case sw::FORMAT_R8I_SNORM:
case sw::FORMAT_R16F:
case sw::FORMAT_R32F: return GL_RED;
default: default:
UNREACHABLE(colorbuffer->getInternalFormat()); UNREACHABLE(colorbuffer->getInternalFormat());
} }
...@@ -472,12 +507,49 @@ GLenum Framebuffer::getImplementationColorReadType() ...@@ -472,12 +507,49 @@ GLenum Framebuffer::getImplementationColorReadType()
{ {
switch(colorbuffer->getInternalFormat()) switch(colorbuffer->getInternalFormat())
{ {
case sw::FORMAT_A16B16G16R16F: return (egl::getClientVersion() < 3) ? GL_HALF_FLOAT_OES : GL_HALF_FLOAT; case sw::FORMAT_R16F:
case sw::FORMAT_G16R16F:
case sw::FORMAT_B16G16R16F:
case sw::FORMAT_A16B16G16R16F:
case sw::FORMAT_R32F:
case sw::FORMAT_G32R32F:
case sw::FORMAT_B32G32R32F:
case sw::FORMAT_A32B32G32R32F: return GL_FLOAT; case sw::FORMAT_A32B32G32R32F: return GL_FLOAT;
case sw::FORMAT_A8R8G8B8: return GL_UNSIGNED_BYTE; case sw::FORMAT_R8I_SNORM:
case sw::FORMAT_A8B8G8R8: return GL_UNSIGNED_BYTE; case sw::FORMAT_G8R8I_SNORM:
case sw::FORMAT_X8R8G8B8: return GL_UNSIGNED_BYTE; case sw::FORMAT_X8B8G8R8I_SNORM:
case sw::FORMAT_A8B8G8R8I_SNORM:return GL_BYTE;
case sw::FORMAT_R8:
case sw::FORMAT_G8R8:
case sw::FORMAT_A8R8G8B8:
case sw::FORMAT_A8B8G8R8:
case sw::FORMAT_X8R8G8B8:
case sw::FORMAT_X8B8G8R8: return GL_UNSIGNED_BYTE; case sw::FORMAT_X8B8G8R8: return GL_UNSIGNED_BYTE;
case sw::FORMAT_R8I:
case sw::FORMAT_G8R8I:
case sw::FORMAT_X8B8G8R8I:
case sw::FORMAT_A8B8G8R8I:
case sw::FORMAT_R16I:
case sw::FORMAT_G16R16I:
case sw::FORMAT_X16B16G16R16I:
case sw::FORMAT_A16B16G16R16I:
case sw::FORMAT_R32I:
case sw::FORMAT_G32R32I:
case sw::FORMAT_X32B32G32R32I:
case sw::FORMAT_A32B32G32R32I: return GL_INT;
case sw::FORMAT_R8UI:
case sw::FORMAT_G8R8UI:
case sw::FORMAT_X8B8G8R8UI:
case sw::FORMAT_A8B8G8R8UI:
case sw::FORMAT_R16UI:
case sw::FORMAT_G16R16UI:
case sw::FORMAT_X16B16G16R16UI:
case sw::FORMAT_A16B16G16R16UI:
case sw::FORMAT_R32UI:
case sw::FORMAT_G32R32UI:
case sw::FORMAT_X32B32G32R32UI:
case sw::FORMAT_A32B32G32R32UI:return GL_UNSIGNED_INT;
case sw::FORMAT_A2B10G10R10: return GL_UNSIGNED_INT_10_10_10_2_OES;
case sw::FORMAT_A1R5G5B5: return GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT; case sw::FORMAT_A1R5G5B5: return GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT;
case sw::FORMAT_R5G6B5: return GL_UNSIGNED_SHORT_5_6_5; case sw::FORMAT_R5G6B5: return GL_UNSIGNED_SHORT_5_6_5;
default: default:
......
...@@ -4744,6 +4744,14 @@ void RenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum ...@@ -4744,6 +4744,14 @@ void RenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum
case GL_RGBA16I: case GL_RGBA16I:
case GL_RGBA32I: case GL_RGBA32I:
case GL_RGBA32UI: case GL_RGBA32UI:
case GL_R16F:
case GL_RG16F:
case GL_R11F_G11F_B10F:
case GL_RGBA16F:
case GL_R32F:
case GL_RG32F:
case GL_RGB32F:
case GL_RGBA32F:
if(clientVersion < 3) if(clientVersion < 3)
{ {
return error(GL_INVALID_ENUM); return error(GL_INVALID_ENUM);
...@@ -4760,6 +4768,7 @@ void RenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum ...@@ -4760,6 +4768,7 @@ void RenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum
context->setRenderbufferStorage(new es2::Stencilbuffer(width, height, samples)); context->setRenderbufferStorage(new es2::Stencilbuffer(width, height, samples));
break; break;
case GL_DEPTH32F_STENCIL8: case GL_DEPTH32F_STENCIL8:
case GL_DEPTH_COMPONENT32_OES:
if(clientVersion < 3) if(clientVersion < 3)
{ {
return error(GL_INVALID_ENUM); return error(GL_INVALID_ENUM);
......
...@@ -3951,7 +3951,7 @@ GL_APICALL void GL_APIENTRY glGetInternalformativ(GLenum target, GLenum internal ...@@ -3951,7 +3951,7 @@ GL_APICALL void GL_APIENTRY glGetInternalformativ(GLenum target, GLenum internal
return error(GL_INVALID_VALUE); return error(GL_INVALID_VALUE);
} }
if(!IsColorRenderable(internalformat) && !IsDepthRenderable(internalformat) && !IsStencilRenderable(internalformat)) if(!IsColorRenderable(internalformat, egl::getClientVersion()) && !IsDepthRenderable(internalformat) && !IsStencilRenderable(internalformat))
{ {
return error(GL_INVALID_ENUM); return error(GL_INVALID_ENUM);
} }
......
...@@ -42,6 +42,7 @@ namespace es2 ...@@ -42,6 +42,7 @@ namespace es2
bool IsCompressed(GLenum format, egl::GLint clientVersion); bool IsCompressed(GLenum format, egl::GLint clientVersion);
GLenum ValidateCompressedFormat(GLenum format, egl::GLint clientVersion, bool expectCompressedFormats); GLenum ValidateCompressedFormat(GLenum format, egl::GLint clientVersion, bool expectCompressedFormats);
bool ValidReadPixelsFormatType(GLenum internalFormat, GLenum internalType, GLenum format, GLenum type, egl::GLint clientVersion);
bool IsDepthTexture(GLenum format); bool IsDepthTexture(GLenum format);
bool IsStencilTexture(GLenum format); bool IsStencilTexture(GLenum format);
bool IsCubemapTextureTarget(GLenum target); bool IsCubemapTextureTarget(GLenum target);
...@@ -49,7 +50,7 @@ namespace es2 ...@@ -49,7 +50,7 @@ namespace es2
bool IsTextureTarget(GLenum target); bool IsTextureTarget(GLenum target);
bool CheckTextureFormatType(GLenum format, GLenum type, egl::GLint clientVersion); bool CheckTextureFormatType(GLenum format, GLenum type, egl::GLint clientVersion);
bool IsColorRenderable(GLenum internalformat); bool IsColorRenderable(GLenum internalformat, egl::GLint clientVersion);
bool IsDepthRenderable(GLenum internalformat); bool IsDepthRenderable(GLenum internalformat);
bool IsStencilRenderable(GLenum internalformat); bool IsStencilRenderable(GLenum internalformat);
......
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