Commit 3d7a0959 by Nicolas Capens

Fix texture uploads using different formats.

Bug 21716622 Change-Id: I3154fc0c3da5c9f2f280101e8e5840ca45eb144e Reviewed-on: https://swiftshader-review.googlesource.com/3446Reviewed-by: 's avatarNicolas Capens <capn@google.com> Tested-by: 's avatarNicolas Capens <capn@google.com>
parent 2c4edc2f
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "Image.hpp" #include "Image.hpp"
#include "Renderer/Blitter.hpp"
#include "../libEGL/Texture.hpp" #include "../libEGL/Texture.hpp"
#include "../common/debug.h" #include "../common/debug.h"
#include "Common/Thread.hpp" #include "Common/Thread.hpp"
...@@ -356,6 +357,77 @@ namespace ...@@ -356,6 +357,77 @@ namespace
namespace egl namespace egl
{ {
sw::Format ConvertFormatType(GLenum format, GLenum type)
{
switch(format)
{
case GL_LUMINANCE:
switch(type)
{
case GL_UNSIGNED_BYTE: return sw::FORMAT_L8;
case GL_HALF_FLOAT: return sw::FORMAT_L16F;
case GL_HALF_FLOAT_OES: return sw::FORMAT_L16F;
case GL_FLOAT: return sw::FORMAT_L32F;
default: UNREACHABLE();
}
break;
case GL_LUMINANCE_ALPHA:
switch(type)
{
case GL_UNSIGNED_BYTE: return sw::FORMAT_A8L8;
case GL_HALF_FLOAT: return sw::FORMAT_A16L16F;
case GL_HALF_FLOAT_OES: return sw::FORMAT_A16L16F;
case GL_FLOAT: return sw::FORMAT_A32L32F;
default: UNREACHABLE();
}
break;
case GL_RGBA:
switch(type)
{
case GL_UNSIGNED_BYTE: return sw::FORMAT_A8B8G8R8;
case GL_UNSIGNED_SHORT_4_4_4_4: return sw::FORMAT_R4G4B4A4;
case GL_UNSIGNED_SHORT_5_5_5_1: return sw::FORMAT_R5G5B5A1;
case GL_HALF_FLOAT: return sw::FORMAT_A16B16G16R16F;
case GL_HALF_FLOAT_OES: return sw::FORMAT_A16B16G16R16F;
case GL_FLOAT: return sw::FORMAT_A32B32G32R32F;
default: UNREACHABLE();
}
break;
case GL_BGRA_EXT:
switch(type)
{
case GL_UNSIGNED_BYTE: return sw::FORMAT_A8R8G8B8;
default: UNREACHABLE();
}
break;
case GL_RGB:
switch(type)
{
case GL_UNSIGNED_BYTE: return sw::FORMAT_B8G8R8;
case GL_UNSIGNED_SHORT_5_6_5: return sw::FORMAT_R5G6B5;
case GL_HALF_FLOAT: return sw::FORMAT_B16G16R16F;
case GL_HALF_FLOAT_OES: return sw::FORMAT_B16G16R16F;
case GL_FLOAT: return sw::FORMAT_B32G32R32F;
default: UNREACHABLE();
}
break;
case GL_ALPHA:
switch(type)
{
case GL_UNSIGNED_BYTE: return sw::FORMAT_A8;
case GL_HALF_FLOAT: return sw::FORMAT_A16F;
case GL_HALF_FLOAT_OES: return sw::FORMAT_A16F;
case GL_FLOAT: return sw::FORMAT_A32F;
default: UNREACHABLE();
}
break;
default:
UNREACHABLE();
}
return sw::FORMAT_NULL;
}
sw::Format SelectInternalFormat(GLenum format, GLenum type) sw::Format SelectInternalFormat(GLenum format, GLenum type)
{ {
if(format == GL_ETC1_RGB8_OES) if(format == GL_ETC1_RGB8_OES)
...@@ -588,119 +660,130 @@ namespace egl ...@@ -588,119 +660,130 @@ namespace egl
GLsizei inputPitch = (unpackInfo.rowLength == 0) ? ComputePitch(width, format, type, unpackInfo.alignment) : unpackInfo.rowLength; GLsizei inputPitch = (unpackInfo.rowLength == 0) ? ComputePitch(width, format, type, unpackInfo.alignment) : unpackInfo.rowLength;
GLsizei inputHeight = (unpackInfo.imageHeight == 0) ? height : unpackInfo.imageHeight; GLsizei inputHeight = (unpackInfo.imageHeight == 0) ? height : unpackInfo.imageHeight;
input = ((char*)input) + (unpackInfo.skipImages * inputHeight + unpackInfo.skipRows) * inputPitch + unpackInfo.skipPixels; input = ((char*)input) + (unpackInfo.skipImages * inputHeight + unpackInfo.skipRows) * inputPitch + unpackInfo.skipPixels;
void *buffer = lock(0, 0, sw::LOCK_WRITEONLY);
if(buffer) if(SelectInternalFormat(format, type) == internalFormat)
{ {
switch(type) void *buffer = lock(0, 0, sw::LOCK_WRITEONLY);
if(buffer)
{ {
case GL_UNSIGNED_BYTE: switch(type)
switch(format)
{
case GL_ALPHA:
LoadImageData<Alpha>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat);
break;
case GL_LUMINANCE:
LoadImageData<Luminance>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat);
break;
case GL_LUMINANCE_ALPHA:
LoadImageData<LuminanceAlpha>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat);
break;
case GL_RGB:
LoadImageData<UByteRGB>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat);
break;
case GL_RGBA:
case GL_BGRA_EXT:
LoadImageData<UByte4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat);
break;
default: UNREACHABLE();
}
break;
case GL_UNSIGNED_SHORT_5_6_5:
switch(format)
{
case GL_RGB:
LoadImageData<RGB565>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat);
break;
default: UNREACHABLE();
}
break;
case GL_UNSIGNED_SHORT_4_4_4_4:
switch(format)
{
case GL_RGBA:
LoadImageData<RGBA4444>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat);
break;
default: UNREACHABLE();
}
break;
case GL_UNSIGNED_SHORT_5_5_5_1:
switch(format)
{ {
case GL_RGBA: case GL_UNSIGNED_BYTE:
LoadImageData<RGBA5551>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat); switch(format)
{
case GL_ALPHA:
LoadImageData<Alpha>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat);
break;
case GL_LUMINANCE:
LoadImageData<Luminance>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat);
break;
case GL_LUMINANCE_ALPHA:
LoadImageData<LuminanceAlpha>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat);
break;
case GL_RGB:
LoadImageData<UByteRGB>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat);
break;
case GL_RGBA:
case GL_BGRA_EXT:
LoadImageData<UByte4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat);
break;
default: UNREACHABLE();
}
break; break;
default: UNREACHABLE(); case GL_UNSIGNED_SHORT_5_6_5:
} switch(format)
break; {
case GL_FLOAT: case GL_RGB:
switch(format) LoadImageData<RGB565>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat);
{ break;
// float textures are converted to RGBA, not BGRA default: UNREACHABLE();
case GL_ALPHA: }
LoadImageData<AlphaFloat>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat);
break;
case GL_LUMINANCE:
LoadImageData<LuminanceFloat>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat);
break; break;
case GL_LUMINANCE_ALPHA: case GL_UNSIGNED_SHORT_4_4_4_4:
LoadImageData<LuminanceAlphaFloat>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat); switch(format)
{
case GL_RGBA:
LoadImageData<RGBA4444>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat);
break;
default: UNREACHABLE();
}
break; break;
case GL_RGB: case GL_UNSIGNED_SHORT_5_5_5_1:
LoadImageData<FloatRGB>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat); switch(format)
{
case GL_RGBA:
LoadImageData<RGBA5551>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat);
break;
default: UNREACHABLE();
}
break; break;
case GL_RGBA: case GL_FLOAT:
LoadImageData<Float4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat); switch(format)
break; {
default: UNREACHABLE(); // float textures are converted to RGBA, not BGRA
} case GL_ALPHA:
break; LoadImageData<AlphaFloat>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat);
case GL_HALF_FLOAT: break;
case GL_HALF_FLOAT_OES: case GL_LUMINANCE:
switch(format) LoadImageData<LuminanceFloat>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat);
{ break;
case GL_ALPHA: case GL_LUMINANCE_ALPHA:
LoadImageData<AlphaHalfFloat>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat); LoadImageData<LuminanceAlphaFloat>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat);
break;
case GL_RGB:
LoadImageData<FloatRGB>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat);
break;
case GL_RGBA:
LoadImageData<Float4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat);
break;
default: UNREACHABLE();
}
break; break;
case GL_LUMINANCE: case GL_HALF_FLOAT:
LoadImageData<LuminanceHalfFloat>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat); case GL_HALF_FLOAT_OES:
switch(format)
{
case GL_ALPHA:
LoadImageData<AlphaHalfFloat>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat);
break;
case GL_LUMINANCE:
LoadImageData<LuminanceHalfFloat>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat);
break;
case GL_LUMINANCE_ALPHA:
LoadImageData<LuminanceAlphaHalfFloat>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat);
break;
case GL_RGB:
LoadImageData<HalfFloatRGB>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat);
break;
case GL_RGBA:
LoadImageData<HalfFloat4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat);
break;
default: UNREACHABLE();
}
break; break;
case GL_LUMINANCE_ALPHA: case GL_UNSIGNED_SHORT:
LoadImageData<LuminanceAlphaHalfFloat>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat); LoadImageData<D16>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat);
break; break;
case GL_RGB: case GL_UNSIGNED_INT:
LoadImageData<HalfFloatRGB>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat); LoadImageData<D32>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat);
break; break;
case GL_RGBA: case GL_UNSIGNED_INT_24_8_OES:
LoadImageData<HalfFloat4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat); loadD24S8ImageData(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, input, buffer);
break; break;
default: UNREACHABLE(); default: UNREACHABLE();
} }
break;
case GL_UNSIGNED_SHORT:
LoadImageData<D16>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat);
break;
case GL_UNSIGNED_INT:
LoadImageData<D32>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer, internalFormat);
break;
case GL_UNSIGNED_INT_24_8_OES:
loadD24S8ImageData(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, input, buffer);
break;
default: UNREACHABLE();
} }
}
unlock(); unlock();
}
else
{
sw::Surface source(width, height, depth, ConvertFormatType(format, type), const_cast<void*>(input), inputPitch, inputPitch * inputHeight);
sw::Rect sourceRect(0, 0, width, height);
sw::Rect destRect(xoffset, yoffset, xoffset + width, yoffset + height);
sw::blitter.blit(&source, sourceRect, this, destRect, false);
}
} }
void Image::loadD24S8ImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, int inputPitch, int inputHeight, const void *input, void *buffer) void Image::loadD24S8ImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, int inputPitch, int inputHeight, const void *input, void *buffer)
......
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