D3D11: Fix loading of RGB5A1 data from RGBA8.
BUG=angleproject:1407
BUG=chromium:616176
Change-Id: I2b88616b6b72dd9caf07fac8ebba9a065cf2983f
Reviewed-on: https://chromium-review.googlesource.com/350907
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 9909fc8..0a10105 100644
--- a/src/libANGLE/renderer/d3d/d3d11/load_functions_data.json
+++ b/src/libANGLE/renderer/d3d/d3d11/load_functions_data.json
@@ -291,6 +291,11 @@
"loadFunction": "LoadToNative<GLubyte,4>",
"dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
"requiresConversion": "false"
+ },
+ {
+ "loadFunction": "LoadRGBA8ToBGR5A1",
+ "dxgiFormat": "DXGI_FORMAT_B5G5R5A1_UNORM",
+ "requiresConversion": "true"
}
],
"GL_UNSIGNED_SHORT_5_5_5_1": [
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 aa88f70..dc47b14 100644
--- a/src/libANGLE/renderer/d3d/d3d11/load_functions_table_autogen.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/load_functions_table_autogen.cpp
@@ -1549,6 +1549,7 @@
{
static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = {
{ GL_UNSIGNED_SHORT_5_5_5_1, LoadImageFunctionInfo(LoadRGB5A1ToA1RGB5, true) },
+ { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadRGBA8ToBGR5A1, true) },
};
return loadFunctionsMap;
diff --git a/src/libANGLE/renderer/d3d/loadimage.cpp b/src/libANGLE/renderer/d3d/loadimage.cpp
index a5c69be..79e2dcf 100644
--- a/src/libANGLE/renderer/d3d/loadimage.cpp
+++ b/src/libANGLE/renderer/d3d/loadimage.cpp
@@ -495,6 +495,37 @@
}
}
+void LoadRGBA8ToBGR5A1(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 uint32_t *source =
+ OffsetDataPointer<uint32_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++)
+ {
+ uint32_t rgba8 = source[x];
+ auto r5 = static_cast<uint16_t>((rgba8 & 0x000000FF) >> 3);
+ auto g5 = static_cast<uint16_t>((rgba8 & 0x0000FF00) >> 11);
+ auto b5 = static_cast<uint16_t>((rgba8 & 0x00FF0000) >> 19);
+ auto a1 = static_cast<uint16_t>((rgba8 & 0xFF000000) >> 31);
+ dest[x] = (a1 << 15) | (r5 << 10) | (g5 << 5) | b5;
+ }
+ }
+ }
+}
+
void LoadRGB5A1ToA1RGB5(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 3cf7d8e..72a4690 100644
--- a/src/libANGLE/renderer/d3d/loadimage.h
+++ b/src/libANGLE/renderer/d3d/loadimage.h
@@ -132,6 +132,16 @@
const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+void LoadRGBA8ToBGR5A1(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 LoadRGB5A1ToA1RGB5(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 56a92de..51e5028 100644
--- a/src/tests/gl_tests/SixteenBppTextureTest.cpp
+++ b/src/tests/gl_tests/SixteenBppTextureTest.cpp
@@ -324,6 +324,25 @@
simpleValidationBase(tex.get());
}
+// Test uploading RGBA8 data to RGB5A41 textures.
+TEST_P(SixteenBppTextureTestES3, RGB5A1UploadRGBA8)
+{
+ std::vector<GLColor> fourColors;
+ fourColors.push_back(GLColor::red);
+ fourColors.push_back(GLColor::green);
+ fourColors.push_back(GLColor::blue);
+ fourColors.push_back(GLColor::yellow);
+
+ GLTexture tex;
+ glBindTexture(GL_TEXTURE_2D, tex.get());
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5_A1, 2, 2, 0, GL_RGBA, 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(),