D3D11: Fix loading of RGBA8 data to RGB565.
BUG=angleproject:1407
BUG=chromium:616176
Change-Id: I663d265abfabb88a5aca8ca0002d2cbc29f6b069
Reviewed-on: https://chromium-review.googlesource.com/350906
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/renderer/d3d/d3d11/load_functions_data.json b/src/libANGLE/renderer/d3d/d3d11/load_functions_data.json
index c4483b3..9909fc8 100644
--- a/src/libANGLE/renderer/d3d/d3d11/load_functions_data.json
+++ b/src/libANGLE/renderer/d3d/d3d11/load_functions_data.json
@@ -943,6 +943,11 @@
"loadFunction": "LoadToNative3To4<GLubyte,0xFF>",
"dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
"requiresConversion": "true"
+ },
+ {
+ "loadFunction": "LoadRGB8ToBGR565",
+ "dxgiFormat": "DXGI_FORMAT_B5G6R5_UNORM",
+ "requiresConversion": "true"
}
],
"GL_UNSIGNED_SHORT_5_6_5": [
diff --git a/src/libANGLE/renderer/d3d/d3d11/load_functions_table_autogen.cpp b/src/libANGLE/renderer/d3d/d3d11/load_functions_table_autogen.cpp
index 6ed4825..aa88f70 100644
--- a/src/libANGLE/renderer/d3d/d3d11/load_functions_table_autogen.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/load_functions_table_autogen.cpp
@@ -1522,6 +1522,7 @@
case DXGI_FORMAT_B5G6R5_UNORM:
{
static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = {
+ { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadRGB8ToBGR565, true) },
{ GL_UNSIGNED_SHORT_5_6_5, LoadImageFunctionInfo(LoadToNative<GLushort,1>, false) },
};
diff --git a/src/libANGLE/renderer/d3d/loadimage.cpp b/src/libANGLE/renderer/d3d/loadimage.cpp
index 40f5042..a5c69be 100644
--- a/src/libANGLE/renderer/d3d/loadimage.cpp
+++ b/src/libANGLE/renderer/d3d/loadimage.cpp
@@ -222,6 +222,38 @@
}
}
+void LoadRGB8ToBGR565(size_t width,
+ size_t height,
+ size_t depth,
+ const uint8_t *input,
+ size_t inputRowPitch,
+ size_t inputDepthPitch,
+ uint8_t *output,
+ size_t outputRowPitch,
+ size_t outputDepthPitch)
+{
+ for (size_t z = 0; z < depth; z++)
+ {
+ for (size_t y = 0; y < height; y++)
+ {
+ const uint8_t *source =
+ OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
+ uint16_t *dest =
+ OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
+ for (size_t x = 0; x < width; x++)
+ {
+ uint8_t r8 = source[x * 3 + 0];
+ uint8_t g8 = source[x * 3 + 1];
+ uint8_t b8 = source[x * 3 + 2];
+ auto r5 = static_cast<uint16_t>(r8 >> 3);
+ auto g6 = static_cast<uint16_t>(g8 >> 2);
+ auto b5 = static_cast<uint16_t>(b8 >> 3);
+ dest[x] = (r5 << 11) | (g6 << 5) | b5;
+ }
+ }
+ }
+}
+
void LoadRGB8ToBGRX8(size_t width, size_t height, size_t depth,
const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
diff --git a/src/libANGLE/renderer/d3d/loadimage.h b/src/libANGLE/renderer/d3d/loadimage.h
index 4426225..3cf7d8e 100644
--- a/src/libANGLE/renderer/d3d/loadimage.h
+++ b/src/libANGLE/renderer/d3d/loadimage.h
@@ -80,6 +80,16 @@
const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+void LoadRGB8ToBGR565(size_t width,
+ size_t height,
+ size_t depth,
+ const uint8_t *input,
+ size_t inputRowPitch,
+ size_t inputDepthPitch,
+ uint8_t *output,
+ size_t outputRowPitch,
+ size_t outputDepthPitch);
+
void LoadR5G6B5ToBGRA8(size_t width, size_t height, size_t depth,
const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
diff --git a/src/tests/gl_tests/SixteenBppTextureTest.cpp b/src/tests/gl_tests/SixteenBppTextureTest.cpp
index eda6039..56a92de 100644
--- a/src/tests/gl_tests/SixteenBppTextureTest.cpp
+++ b/src/tests/gl_tests/SixteenBppTextureTest.cpp
@@ -303,6 +303,27 @@
simpleValidationBase(tex.get());
}
+// Test uploading RGB8 data to RGB565 textures.
+TEST_P(SixteenBppTextureTestES3, RGB565UploadRGB8)
+{
+ std::vector<GLColorRGB> fourColors;
+ fourColors.push_back(GLColorRGB::red);
+ fourColors.push_back(GLColorRGB::green);
+ fourColors.push_back(GLColorRGB::blue);
+ fourColors.push_back(GLColorRGB::yellow);
+
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+ GLTexture tex;
+ glBindTexture(GL_TEXTURE_2D, tex.get());
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB565, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, fourColors.data());
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ ASSERT_GL_NO_ERROR();
+
+ simpleValidationBase(tex.get());
+}
+
// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
ANGLE_INSTANTIATE_TEST(SixteenBppTextureTest,
ES2_D3D9(),
diff --git a/src/tests/test_utils/ANGLETest.cpp b/src/tests/test_utils/ANGLETest.cpp
index a9032a1..d30fc70 100644
--- a/src/tests/test_utils/ANGLETest.cpp
+++ b/src/tests/test_utils/ANGLETest.cpp
@@ -15,6 +15,11 @@
namespace angle
{
+const GLColorRGB GLColorRGB::blue(0u, 0u, 255u);
+const GLColorRGB GLColorRGB::green(0u, 255u, 0u);
+const GLColorRGB GLColorRGB::red(255u, 0u, 0u);
+const GLColorRGB GLColorRGB::yellow(255u, 255u, 0);
+
const GLColor GLColor::black = GLColor(0u, 0u, 0u, 255u);
const GLColor GLColor::blue = GLColor(0u, 0u, 255u, 255u);
const GLColor GLColor::cyan = GLColor(0u, 255u, 255u, 255u);
@@ -86,6 +91,14 @@
TestPlatform g_testPlatformInstance;
} // anonymous namespace
+GLColorRGB::GLColorRGB() : R(0), G(0), B(0)
+{
+}
+
+GLColorRGB::GLColorRGB(GLubyte r, GLubyte g, GLubyte b) : R(r), G(g), B(b)
+{
+}
+
GLColor::GLColor() : R(0), G(0), B(0), A(0)
{
}
diff --git a/src/tests/test_utils/ANGLETest.h b/src/tests/test_utils/ANGLETest.h
index a14bd0a..a590f9f 100644
--- a/src/tests/test_utils/ANGLETest.h
+++ b/src/tests/test_utils/ANGLETest.h
@@ -44,6 +44,19 @@
namespace angle
{
+struct GLColorRGB
+{
+ GLColorRGB();
+ GLColorRGB(GLubyte r, GLubyte g, GLubyte b);
+
+ GLubyte R, G, B;
+
+ static const GLColorRGB blue;
+ static const GLColorRGB green;
+ static const GLColorRGB red;
+ static const GLColorRGB yellow;
+};
+
struct GLColor
{
GLColor();