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
......@@ -165,8 +165,10 @@ Context::Context(const egl::Config *config, const Context *shareContext, EGLint
mState.packAlignment = 4;
mState.unpackInfo.alignment = 4;
mState.packRowLength = 0;
mState.packImageHeight = 0;
mState.packSkipPixels = 0;
mState.packSkipRows = 0;
mState.packSkipImages = 0;
mState.unpackInfo.rowLength = 0;
mState.unpackInfo.imageHeight = 0;
mState.unpackInfo.skipPixels = 0;
......@@ -848,6 +850,11 @@ void Context::setPackRowLength(GLint rowLength)
mState.packRowLength = rowLength;
}
void Context::setPackImageHeight(GLint imageHeight)
{
mState.packImageHeight = imageHeight;
}
void Context::setPackSkipPixels(GLint skipPixels)
{
mState.packSkipPixels = skipPixels;
......@@ -858,6 +865,11 @@ void Context::setPackSkipRows(GLint skipRows)
mState.packSkipRows = skipRows;
}
void Context::setPackSkipImages(GLint skipImages)
{
mState.packSkipImages = skipImages;
}
void Context::setUnpackRowLength(GLint rowLength)
{
mState.unpackInfo.rowLength = rowLength;
......@@ -3262,15 +3274,18 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
return error(GL_INVALID_OPERATION);
}
if(format != GL_RGBA || type != GL_UNSIGNED_BYTE)
GLenum readFormat = framebuffer->getImplementationColorReadFormat();
GLenum readType = framebuffer->getImplementationColorReadType();
if(!(readFormat == format && readType == type) && !ValidReadPixelsFormatType(readFormat, readType, format, type, clientVersion))
{
if(format != framebuffer->getImplementationColorReadFormat() || type != framebuffer->getImplementationColorReadType())
{
return error(GL_INVALID_OPERATION);
}
return error(GL_INVALID_OPERATION);
}
GLsizei outputPitch = (mState.packRowLength > 0) ? mState.packRowLength : egl::ComputePitch(width, format, type, mState.packAlignment);
GLsizei outputPitch = egl::ComputePitch((mState.packRowLength > 0) ? mState.packRowLength : width, format, type, mState.packAlignment);
GLsizei outputHeight = (mState.packImageHeight == 0) ? height : mState.packImageHeight;
pixels = getPixelPackBuffer() ? (unsigned char*)getPixelPackBuffer()->data() + (ptrdiff_t)pixels : (unsigned char*)pixels;
pixels = ((char*)pixels) + (mState.packSkipImages * outputHeight + mState.packSkipRows) * outputPitch + mState.packSkipPixels;
// Sized query sanity check
if(bufSize)
......@@ -3292,256 +3307,13 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
x += mState.packSkipPixels;
y += mState.packSkipRows;
sw::Rect rect = {x, y, x + width, y + height};
sw::Rect dstRect = { 0, 0, width, height };
rect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());
unsigned char *source = (unsigned char*)renderTarget->lock(rect.x0, rect.y0, sw::LOCK_READONLY);
unsigned char *dest = getPixelPackBuffer() ? (unsigned char*)getPixelPackBuffer()->data() + (ptrdiff_t)pixels : (unsigned char*)pixels;
int inputPitch = (int)renderTarget->getPitch();
for(int j = 0; j < rect.y1 - rect.y0; j++)
{
unsigned short *dest16 = (unsigned short*)dest;
unsigned int *dest32 = (unsigned int*)dest;
if(renderTarget->getInternalFormat() == sw::FORMAT_A8B8G8R8 &&
format == GL_RGBA && type == GL_UNSIGNED_BYTE)
{
memcpy(dest, source, (rect.x1 - rect.x0) * 4);
}
else if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 &&
format == GL_RGBA && type == GL_UNSIGNED_BYTE)
{
for(int i = 0; i < rect.x1 - rect.x0; i++)
{
unsigned int argb = *(unsigned int*)(source + 4 * i);
dest32[i] = (argb & 0xFF00FF00) | ((argb & 0x000000FF) << 16) | ((argb & 0x00FF0000) >> 16);
}
}
else if(renderTarget->getInternalFormat() == sw::FORMAT_X8R8G8B8 &&
format == GL_RGBA && type == GL_UNSIGNED_BYTE)
{
for(int i = 0; i < rect.x1 - rect.x0; i++)
{
unsigned int xrgb = *(unsigned int*)(source + 4 * i);
dest32[i] = (xrgb & 0xFF00FF00) | ((xrgb & 0x000000FF) << 16) | ((xrgb & 0x00FF0000) >> 16) | 0xFF000000;
}
}
else if(renderTarget->getInternalFormat() == sw::FORMAT_X8R8G8B8 &&
format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE)
{
for(int i = 0; i < rect.x1 - rect.x0; i++)
{
unsigned int xrgb = *(unsigned int*)(source + 4 * i);
dest32[i] = xrgb | 0xFF000000;
}
}
else if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 &&
format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE)
{
memcpy(dest, source, (rect.x1 - rect.x0) * 4);
}
else if(renderTarget->getInternalFormat() == sw::FORMAT_A16B16G16R16F &&
format == GL_RGBA && (type == GL_HALF_FLOAT || type == GL_HALF_FLOAT_OES))
{
memcpy(dest, source, (rect.x1 - rect.x0) * 8);
}
else if(renderTarget->getInternalFormat() == sw::FORMAT_A32B32G32R32F &&
format == GL_RGBA && type == GL_FLOAT)
{
memcpy(dest, source, (rect.x1 - rect.x0) * 16);
}
else if(renderTarget->getInternalFormat() == sw::FORMAT_A1R5G5B5 &&
format == GL_BGRA_EXT && type == GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT)
{
memcpy(dest, source, (rect.x1 - rect.x0) * 2);
}
else if(renderTarget->getInternalFormat() == sw::FORMAT_R5G6B5 &&
format == 0x80E0 && type == GL_UNSIGNED_SHORT_5_6_5) // GL_BGR_EXT
{
memcpy(dest, source, (rect.x1 - rect.x0) * 2);
}
else
{
for(int i = 0; i < rect.x1 - rect.x0; i++)
{
float r;
float g;
float b;
float a;
switch(renderTarget->getInternalFormat())
{
case sw::FORMAT_R5G6B5:
{
unsigned short rgb = *(unsigned short*)(source + 2 * i);
a = 1.0f;
b = (rgb & 0x001F) * (1.0f / 0x001F);
g = (rgb & 0x07E0) * (1.0f / 0x07E0);
r = (rgb & 0xF800) * (1.0f / 0xF800);
}
break;
case sw::FORMAT_A1R5G5B5:
{
unsigned short argb = *(unsigned short*)(source + 2 * i);
a = (argb & 0x8000) ? 1.0f : 0.0f;
b = (argb & 0x001F) * (1.0f / 0x001F);
g = (argb & 0x03E0) * (1.0f / 0x03E0);
r = (argb & 0x7C00) * (1.0f / 0x7C00);
}
break;
case sw::FORMAT_A8R8G8B8:
{
unsigned int argb = *(unsigned int*)(source + 4 * i);
a = (argb & 0xFF000000) * (1.0f / 0xFF000000);
b = (argb & 0x000000FF) * (1.0f / 0x000000FF);
g = (argb & 0x0000FF00) * (1.0f / 0x0000FF00);
r = (argb & 0x00FF0000) * (1.0f / 0x00FF0000);
}
break;
case sw::FORMAT_A8B8G8R8:
{
unsigned int abgr = *(unsigned int*)(source + 4 * i);
a = (abgr & 0xFF000000) * (1.0f / 0xFF000000);
b = (abgr & 0x00FF0000) * (1.0f / 0x00FF0000);
g = (abgr & 0x0000FF00) * (1.0f / 0x0000FF00);
r = (abgr & 0x000000FF) * (1.0f / 0x000000FF);
}
break;
case sw::FORMAT_X8R8G8B8:
{
unsigned int xrgb = *(unsigned int*)(source + 4 * i);
a = 1.0f;
b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF);
g = (xrgb & 0x0000FF00) * (1.0f / 0x0000FF00);
r = (xrgb & 0x00FF0000) * (1.0f / 0x00FF0000);
}
break;
case sw::FORMAT_X8B8G8R8:
{
unsigned int xbgr = *(unsigned int*)(source + 4 * i);
a = 1.0f;
b = (xbgr & 0x00FF0000) * (1.0f / 0x00FF0000);
g = (xbgr & 0x0000FF00) * (1.0f / 0x0000FF00);
r = (xbgr & 0x000000FF) * (1.0f / 0x000000FF);
}
break;
case sw::FORMAT_A2R10G10B10:
{
unsigned int argb = *(unsigned int*)(source + 4 * i);
a = (argb & 0xC0000000) * (1.0f / 0xC0000000);
b = (argb & 0x000003FF) * (1.0f / 0x000003FF);
g = (argb & 0x000FFC00) * (1.0f / 0x000FFC00);
r = (argb & 0x3FF00000) * (1.0f / 0x3FF00000);
}
break;
case sw::FORMAT_A32B32G32R32F:
{
r = *((float*)(source + 16 * i) + 0);
g = *((float*)(source + 16 * i) + 1);
b = *((float*)(source + 16 * i) + 2);
a = *((float*)(source + 16 * i) + 3);
}
break;
case sw::FORMAT_A16B16G16R16F:
{
r = (float)*((sw::half*)(source + 8 * i) + 0);
g = (float)*((sw::half*)(source + 8 * i) + 1);
b = (float)*((sw::half*)(source + 8 * i) + 2);
a = (float)*((sw::half*)(source + 8 * i) + 3);
}
break;
default:
UNIMPLEMENTED(); // FIXME
UNREACHABLE(renderTarget->getInternalFormat());
}
switch(format)
{
case GL_RGBA:
switch(type)
{
case GL_UNSIGNED_BYTE:
dest[4 * i + 0] = (unsigned char)(255 * r + 0.5f);
dest[4 * i + 1] = (unsigned char)(255 * g + 0.5f);
dest[4 * i + 2] = (unsigned char)(255 * b + 0.5f);
dest[4 * i + 3] = (unsigned char)(255 * a + 0.5f);
break;
default: UNREACHABLE(type);
}
break;
case GL_BGRA_EXT:
switch(type)
{
case GL_UNSIGNED_BYTE:
dest[4 * i + 0] = (unsigned char)(255 * b + 0.5f);
dest[4 * i + 1] = (unsigned char)(255 * g + 0.5f);
dest[4 * i + 2] = (unsigned char)(255 * r + 0.5f);
dest[4 * i + 3] = (unsigned char)(255 * a + 0.5f);
break;
case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
// According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
// this type is packed as follows:
// 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
// --------------------------------------------------------------------------------
// | 4th | 3rd | 2nd | 1st component |
// --------------------------------------------------------------------------------
// in the case of BGRA_EXT, B is the first component, G the second, and so forth.
dest16[i] =
((unsigned short)(15 * a + 0.5f) << 12)|
((unsigned short)(15 * r + 0.5f) << 8) |
((unsigned short)(15 * g + 0.5f) << 4) |
((unsigned short)(15 * b + 0.5f) << 0);
break;
case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
// According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
// this type is packed as follows:
// 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
// --------------------------------------------------------------------------------
// | 4th | 3rd | 2nd | 1st component |
// --------------------------------------------------------------------------------
// in the case of BGRA_EXT, B is the first component, G the second, and so forth.
dest16[i] =
((unsigned short)( a + 0.5f) << 15) |
((unsigned short)(31 * r + 0.5f) << 10) |
((unsigned short)(31 * g + 0.5f) << 5) |
((unsigned short)(31 * b + 0.5f) << 0);
break;
default: UNREACHABLE(type);
}
break;
case GL_RGB:
switch(type)
{
case GL_UNSIGNED_SHORT_5_6_5:
dest16[i] =
((unsigned short)(31 * b + 0.5f) << 0) |
((unsigned short)(63 * g + 0.5f) << 5) |
((unsigned short)(31 * r + 0.5f) << 11);
break;
default: UNREACHABLE(type);
}
break;
default: UNREACHABLE(format);
}
}
}
source += inputPitch;
dest += outputPitch;
}
renderTarget->unlock();
renderTarget->release();
sw::Surface externalSurface(width, height, 1, egl::SelectInternalFormat(format, type), pixels, outputPitch, outputPitch * outputHeight);
sw::SliceRect sliceRect(rect);
sw::SliceRect dstSliceRect(dstRect);
device->blit(renderTarget, sliceRect, &externalSurface, dstSliceRect, false);
}
void Context::clear(GLbitfield mask)
......
......@@ -397,8 +397,10 @@ struct State
egl::Image::UnpackInfo unpackInfo;
GLint packAlignment;
GLint packRowLength;
GLint packImageHeight;
GLint packSkipPixels;
GLint packSkipRows;
GLint packSkipImages;
};
class Context : public egl::Context
......@@ -511,8 +513,10 @@ public:
void setPackAlignment(GLint alignment);
void setPackRowLength(GLint rowLength);
void setPackImageHeight(GLint imageHeight);
void setPackSkipPixels(GLint skipPixels);
void setPackSkipRows(GLint skipRows);
void setPackSkipImages(GLint skipImages);
// These create and destroy methods are merely pass-throughs to
// ResourceManager, which owns these object types
......
......@@ -284,7 +284,7 @@ GLenum Framebuffer::completeness(int &width, int &height, int &samples)
if(mColorbufferType[i] == GL_RENDERBUFFER)
{
if(!es2::IsColorRenderable(colorbuffer->getFormat()))
if(!es2::IsColorRenderable(colorbuffer->getFormat(), egl::getClientVersion()))
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
......@@ -448,14 +448,49 @@ GLenum Framebuffer::getImplementationColorReadFormat()
// Don't return GL_RGBA since that's always supported. Provide a second option here.
switch(colorbuffer->getInternalFormat())
{
case sw::FORMAT_A16B16G16R16F: return GL_BGRA_EXT;
case sw::FORMAT_A32B32G32R32F: return GL_BGRA_EXT;
case sw::FORMAT_A8R8G8B8: return GL_BGRA_EXT;
case sw::FORMAT_A8B8G8R8: return GL_BGRA_EXT;
case sw::FORMAT_X8R8G8B8: return 0x80E0; // GL_BGR_EXT
case sw::FORMAT_X8B8G8R8: return 0x80E0; // GL_BGR_EXT
case sw::FORMAT_A8B8G8R8I:
case sw::FORMAT_A8B8G8R8UI:
case sw::FORMAT_A16B16G16R16I:
case sw::FORMAT_A16B16G16R16UI:
case sw::FORMAT_A32B32G32R32I:
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_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_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:
UNREACHABLE(colorbuffer->getInternalFormat());
}
......@@ -472,12 +507,49 @@ GLenum Framebuffer::getImplementationColorReadType()
{
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_A8R8G8B8: return GL_UNSIGNED_BYTE;
case sw::FORMAT_A8B8G8R8: return GL_UNSIGNED_BYTE;
case sw::FORMAT_X8R8G8B8: return GL_UNSIGNED_BYTE;
case sw::FORMAT_R8I_SNORM:
case sw::FORMAT_G8R8I_SNORM:
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_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_R5G6B5: return GL_UNSIGNED_SHORT_5_6_5;
default:
......
......@@ -4744,6 +4744,14 @@ void RenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum
case GL_RGBA16I:
case GL_RGBA32I:
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)
{
return error(GL_INVALID_ENUM);
......@@ -4760,6 +4768,7 @@ void RenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum
context->setRenderbufferStorage(new es2::Stencilbuffer(width, height, samples));
break;
case GL_DEPTH32F_STENCIL8:
case GL_DEPTH_COMPONENT32_OES:
if(clientVersion < 3)
{
return error(GL_INVALID_ENUM);
......
......@@ -3951,7 +3951,7 @@ GL_APICALL void GL_APIENTRY glGetInternalformativ(GLenum target, GLenum internal
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);
}
......
......@@ -377,6 +377,66 @@ namespace es2
}
}
bool ValidReadPixelsFormatType(GLenum internalFormat, GLenum internalType, GLenum format, GLenum type, egl::GLint clientVersion)
{
switch(format)
{
case GL_RGBA:
switch(type)
{
case GL_UNSIGNED_BYTE:
break;
case GL_UNSIGNED_INT_2_10_10_10_REV:
return (clientVersion >= 3) && (internalFormat == GL_RGB10_A2);
case GL_FLOAT:
return (clientVersion >= 3) && (internalType == GL_FLOAT);
default:
return false;
}
break;
case GL_RGBA_INTEGER:
if(clientVersion < 3)
{
return false;
}
switch(type)
{
case GL_INT:
if(internalType != GL_INT)
{
return false;
}
break;
case GL_UNSIGNED_INT:
if(internalType != GL_UNSIGNED_INT)
{
return false;
}
break;
default:
return false;
}
break;
case GL_BGRA_EXT:
switch(type)
{
case GL_UNSIGNED_BYTE:
case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
break;
default:
return false;
}
break;
case GL_RG_EXT:
case GL_RED_EXT:
return (clientVersion >= 3) && (type == GL_UNSIGNED_BYTE);
default:
return false;
}
return true;
}
bool IsDepthTexture(GLenum format)
{
return format == GL_DEPTH_COMPONENT ||
......@@ -535,7 +595,7 @@ namespace es2
}
}
bool IsColorRenderable(GLenum internalformat)
bool IsColorRenderable(GLenum internalformat, egl::GLint clientVersion)
{
switch(internalformat)
{
......@@ -568,7 +628,18 @@ namespace es2
case GL_RGB8_OES:
case GL_RGBA8_OES:
return true;
case GL_R16F:
case GL_RG16F:
case GL_R11F_G11F_B10F:
case GL_RGB16F:
case GL_RGBA16F:
case GL_R32F:
case GL_RG32F:
case GL_RGB32F:
case GL_RGBA32F:
return clientVersion >= 3;
case GL_DEPTH_COMPONENT24:
case GL_DEPTH_COMPONENT32_OES:
case GL_DEPTH_COMPONENT32F:
case GL_DEPTH32F_STENCIL8:
case GL_DEPTH_COMPONENT16:
......@@ -587,6 +658,7 @@ namespace es2
switch(internalformat)
{
case GL_DEPTH_COMPONENT24:
case GL_DEPTH_COMPONENT32_OES:
case GL_DEPTH_COMPONENT32F:
case GL_DEPTH32F_STENCIL8:
case GL_DEPTH_COMPONENT16:
......@@ -621,6 +693,15 @@ namespace es2
case GL_RGB565:
case GL_RGB8_OES:
case GL_RGBA8_OES:
case GL_R16F:
case GL_RG16F:
case GL_R11F_G11F_B10F:
case GL_RGB16F:
case GL_RGBA16F:
case GL_R32F:
case GL_RG32F:
case GL_RGB32F:
case GL_RGBA32F:
return false;
default:
UNIMPLEMENTED();
......@@ -665,8 +746,18 @@ namespace es2
case GL_RGB565:
case GL_RGB8_OES:
case GL_RGBA8_OES:
case GL_R16F:
case GL_RG16F:
case GL_R11F_G11F_B10F:
case GL_RGB16F:
case GL_RGBA16F:
case GL_R32F:
case GL_RG32F:
case GL_RGB32F:
case GL_RGBA32F:
case GL_DEPTH_COMPONENT16:
case GL_DEPTH_COMPONENT24:
case GL_DEPTH_COMPONENT32_OES:
case GL_DEPTH_COMPONENT32F:
return false;
default:
......@@ -965,7 +1056,46 @@ namespace es2sw
case GL_DEPTH_COMPONENT16:
case GL_STENCIL_INDEX8:
case GL_DEPTH24_STENCIL8_OES: return sw::FORMAT_D24S8;
default: UNREACHABLE(format); return sw::FORMAT_A8B8G8R8;
case GL_DEPTH_COMPONENT32_OES:return sw::FORMAT_D32;
case GL_R8: return sw::FORMAT_R8;
case GL_RG8: return sw::FORMAT_G8R8;
case GL_R8I: return sw::FORMAT_R8I;
case GL_RG8I: return sw::FORMAT_G8R8I;
case GL_RGB8I: return sw::FORMAT_X8B8G8R8I;
case GL_RGBA8I: return sw::FORMAT_A8B8G8R8I;
case GL_R8UI: return sw::FORMAT_R8UI;
case GL_RG8UI: return sw::FORMAT_G8R8UI;
case GL_RGB8UI: return sw::FORMAT_X8B8G8R8UI;
case GL_RGBA8UI: return sw::FORMAT_A8B8G8R8UI;
case GL_R16I: return sw::FORMAT_R16I;
case GL_RG16I: return sw::FORMAT_G16R16I;
case GL_RGB16I: return sw::FORMAT_X16B16G16R16I;
case GL_RGBA16I: return sw::FORMAT_A16B16G16R16I;
case GL_R16UI: return sw::FORMAT_R16UI;
case GL_RG16UI: return sw::FORMAT_G16R16UI;
case GL_RGB16UI: return sw::FORMAT_X16B16G16R16UI;
case GL_RGB10_A2UI:
case GL_RGBA16UI: return sw::FORMAT_A16B16G16R16UI;
case GL_R32I: return sw::FORMAT_R32I;
case GL_RG32I: return sw::FORMAT_G32R32I;
case GL_RGB32I: return sw::FORMAT_X32B32G32R32I;
case GL_RGBA32I: return sw::FORMAT_A32B32G32R32I;
case GL_R32UI: return sw::FORMAT_R32UI;
case GL_RG32UI: return sw::FORMAT_G32R32UI;
case GL_RGB32UI: return sw::FORMAT_X32B32G32R32UI;
case GL_RGBA32UI: return sw::FORMAT_A32B32G32R32UI;
case GL_R16F: return sw::FORMAT_R16F;
case GL_RG16F: return sw::FORMAT_G16R16F;
case GL_R11F_G11F_B10F:
case GL_RGB16F: return sw::FORMAT_B16G16R16F;
case GL_RGBA16F: return sw::FORMAT_A16B16G16R16F;
case GL_R32F: return sw::FORMAT_R32F;
case GL_RG32F: return sw::FORMAT_G32R32F;
case GL_RGB32F: return sw::FORMAT_B32G32R32F;
case GL_RGBA32F: return sw::FORMAT_A32B32G32R32F;
case GL_RGB10_A2: return sw::FORMAT_A2B10G10R10;
case GL_SRGB8_ALPHA8: // FIXME: Implement SRGB
default: UNREACHABLE(format); return sw::FORMAT_NULL;
}
}
}
......@@ -1002,14 +1132,23 @@ namespace sw2es
switch(colorFormat)
{
case sw::FORMAT_A16B16G16R16F:
case sw::FORMAT_A16B16G16R16I:
case sw::FORMAT_A16B16G16R16UI:
return 16;
case sw::FORMAT_A32B32G32R32F:
case sw::FORMAT_A32B32G32R32I:
case sw::FORMAT_A32B32G32R32UI:
return 32;
case sw::FORMAT_A2R10G10B10:
return 2;
case sw::FORMAT_A8R8G8B8:
case sw::FORMAT_A8B8G8R8:
case sw::FORMAT_A8B8G8R8I:
case sw::FORMAT_A8B8G8R8UI:
case sw::FORMAT_A8B8G8R8I_SNORM:
return 8;
case sw::FORMAT_A2B10G10R10:
return 2;
case sw::FORMAT_A1R5G5B5:
return 1;
case sw::FORMAT_X8R8G8B8:
......@@ -1025,16 +1164,53 @@ namespace sw2es
{
switch(colorFormat)
{
case sw::FORMAT_R16F:
case sw::FORMAT_G16R16F:
case sw::FORMAT_B16G16R16F:
case sw::FORMAT_A16B16G16R16F:
case sw::FORMAT_R16I:
case sw::FORMAT_G16R16I:
case sw::FORMAT_X16B16G16R16I:
case sw::FORMAT_A16B16G16R16I:
case sw::FORMAT_R16UI:
case sw::FORMAT_G16R16UI:
case sw::FORMAT_X16B16G16R16UI:
case sw::FORMAT_A16B16G16R16UI:
return 16;
case sw::FORMAT_R32F:
case sw::FORMAT_G32R32F:
case sw::FORMAT_B32G32R32F:
case sw::FORMAT_A32B32G32R32F:
case sw::FORMAT_R32I:
case sw::FORMAT_G32R32I:
case sw::FORMAT_X32B32G32R32I:
case sw::FORMAT_A32B32G32R32I:
case sw::FORMAT_R32UI:
case sw::FORMAT_G32R32UI:
case sw::FORMAT_X32B32G32R32UI:
case sw::FORMAT_A32B32G32R32UI:
return 32;
case sw::FORMAT_A2B10G10R10:
case sw::FORMAT_A2R10G10B10:
return 10;
case sw::FORMAT_A8R8G8B8:
case sw::FORMAT_A8B8G8R8:
case sw::FORMAT_X8R8G8B8:
case sw::FORMAT_X8B8G8R8:
case sw::FORMAT_R8:
case sw::FORMAT_G8R8:
case sw::FORMAT_R8I:
case sw::FORMAT_G8R8I:
case sw::FORMAT_X8B8G8R8I:
case sw::FORMAT_A8B8G8R8I:
case sw::FORMAT_R8UI:
case sw::FORMAT_G8R8UI:
case sw::FORMAT_X8B8G8R8UI:
case sw::FORMAT_A8B8G8R8UI:
case sw::FORMAT_R8I_SNORM:
case sw::FORMAT_G8R8I_SNORM:
case sw::FORMAT_X8B8G8R8I_SNORM:
case sw::FORMAT_A8B8G8R8I_SNORM:
return 8;
case sw::FORMAT_A1R5G5B5:
case sw::FORMAT_R5G6B5:
......@@ -1048,16 +1224,43 @@ namespace sw2es
{
switch(colorFormat)
{
case sw::FORMAT_G16R16F:
case sw::FORMAT_B16G16R16F:
case sw::FORMAT_A16B16G16R16F:
case sw::FORMAT_G16R16I:
case sw::FORMAT_X16B16G16R16I:
case sw::FORMAT_A16B16G16R16I:
case sw::FORMAT_G16R16UI:
case sw::FORMAT_X16B16G16R16UI:
case sw::FORMAT_A16B16G16R16UI:
return 16;
case sw::FORMAT_G32R32F:
case sw::FORMAT_B32G32R32F:
case sw::FORMAT_A32B32G32R32F:
case sw::FORMAT_G32R32I:
case sw::FORMAT_X32B32G32R32I:
case sw::FORMAT_A32B32G32R32I:
case sw::FORMAT_G32R32UI:
case sw::FORMAT_X32B32G32R32UI:
case sw::FORMAT_A32B32G32R32UI:
return 32;
case sw::FORMAT_A2B10G10R10:
case sw::FORMAT_A2R10G10B10:
return 10;
case sw::FORMAT_A8R8G8B8:
case sw::FORMAT_A8B8G8R8:
case sw::FORMAT_X8R8G8B8:
case sw::FORMAT_X8B8G8R8:
case sw::FORMAT_G8R8:
case sw::FORMAT_G8R8I:
case sw::FORMAT_X8B8G8R8I:
case sw::FORMAT_A8B8G8R8I:
case sw::FORMAT_G8R8UI:
case sw::FORMAT_X8B8G8R8UI:
case sw::FORMAT_A8B8G8R8UI:
case sw::FORMAT_G8R8I_SNORM:
case sw::FORMAT_X8B8G8R8I_SNORM:
case sw::FORMAT_A8B8G8R8I_SNORM:
return 8;
case sw::FORMAT_A1R5G5B5:
return 5;
......@@ -1072,16 +1275,33 @@ namespace sw2es
{
switch(colorFormat)
{
case sw::FORMAT_B16G16R16F:
case sw::FORMAT_A16B16G16R16F:
case sw::FORMAT_X16B16G16R16I:
case sw::FORMAT_A16B16G16R16I:
case sw::FORMAT_X16B16G16R16UI:
case sw::FORMAT_A16B16G16R16UI:
return 16;
case sw::FORMAT_B32G32R32F:
case sw::FORMAT_A32B32G32R32F:
case sw::FORMAT_X32B32G32R32I:
case sw::FORMAT_A32B32G32R32I:
case sw::FORMAT_X32B32G32R32UI:
case sw::FORMAT_A32B32G32R32UI:
return 32;
case sw::FORMAT_A2B10G10R10:
case sw::FORMAT_A2R10G10B10:
return 10;
case sw::FORMAT_A8R8G8B8:
case sw::FORMAT_A8B8G8R8:
case sw::FORMAT_X8R8G8B8:
case sw::FORMAT_X8B8G8R8:
case sw::FORMAT_X8B8G8R8I:
case sw::FORMAT_A8B8G8R8I:
case sw::FORMAT_X8B8G8R8UI:
case sw::FORMAT_A8B8G8R8UI:
case sw::FORMAT_X8B8G8R8I_SNORM:
case sw::FORMAT_A8B8G8R8I_SNORM:
return 8;
case sw::FORMAT_A1R5G5B5:
case sw::FORMAT_R5G6B5:
......@@ -1134,9 +1354,44 @@ namespace sw2es
case GL_COLOR_ATTACHMENT15:
switch(format)
{
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_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_R8:
case sw::FORMAT_G8R8:
case sw::FORMAT_A2B10G10R10:
case sw::FORMAT_A2R10G10B10:
case sw::FORMAT_A8R8G8B8:
case sw::FORMAT_A8B8G8R8:
......@@ -1145,6 +1400,11 @@ namespace sw2es
case sw::FORMAT_A1R5G5B5:
case sw::FORMAT_R5G6B5:
return GL_UNSIGNED_NORMALIZED;
case sw::FORMAT_R8I_SNORM:
case sw::FORMAT_X8B8G8R8I_SNORM:
case sw::FORMAT_A8B8G8R8I_SNORM:
case sw::FORMAT_G8R8I_SNORM:
return GL_SIGNED_NORMALIZED;
default:
UNREACHABLE(format);
return 0;
......
......@@ -42,6 +42,7 @@ namespace es2
bool IsCompressed(GLenum format, egl::GLint clientVersion);
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 IsStencilTexture(GLenum format);
bool IsCubemapTextureTarget(GLenum target);
......@@ -49,7 +50,7 @@ namespace es2
bool IsTextureTarget(GLenum target);
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 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