Fix issues with scaling ARGB1555 textures in OpenGL, introduced by the recent merge

This commit is contained in:
Henrik Rydgard 2015-01-20 22:48:39 +01:00
parent 48e4d1edae
commit 08eaa6e1f7
6 changed files with 58 additions and 31 deletions

View File

@ -269,3 +269,15 @@ void ConvertRGBA4444ToRGBA8888(u32 *dst32, const u16 *src, int numPixels) {
dst[x * 4 + 3] = Convert4To8(col >> 12);
}
}
// convert 5551 image to 8888, parallelizable
void ConvertARGB1555ToRGBA8888(u32 *dst32, const u16 *src, int numPixels) {
for (int x = 0; x < numPixels; ++x) {
u32 val = src[x];
u32 r = Convert5To8((val >> 11) & 0x1F);
u32 g = Convert5To8((val >> 6) & 0x1F);
u32 b = Convert5To8((val >> 1) & 0x1F);
u32 a = (val & 0x1) * 255;
dst32[x] = (a << 24) | (b << 16) | (g << 8) | r;
}
}

View File

@ -118,3 +118,7 @@ void ConvertRGBA5551ToRGBA8888(u32 *dst, const u16 *src, int numPixels);
void ConvertRGBA4444ToRGBA8888(u32 *dst, const u16 *src, int numPixels);
void ConvertBGRA8888ToRGBA8888(u32 *dst, const u32 *src, int numPixels);
// Backwards GL Style
void ConvertARGB1555ToRGBA8888(u32 *dst, const u16 *src, int numPixels);

View File

@ -500,7 +500,7 @@ bool TextureScaler::IsEmptyOrFlat(u32* data, int pixels, GLenum fmt) {
return true;
}
void TextureScaler::Scale(u32* &data, GEBufferFormat &dstFmt, int &width, int &height, int factor) {
void TextureScaler::Scale(u32* &data, ScalerPixelFormat &dstFmt, int &width, int &height, int factor) {
// prevent processing empty or flat textures (this happens a lot in some games)
// doesn't hurt the standard case, will be very quick for textures with actual texture
if(IsEmptyOrFlat(data, width*height, dstFmt)) {
@ -547,7 +547,7 @@ void TextureScaler::Scale(u32* &data, GEBufferFormat &dstFmt, int &width, int &h
// update values accordingly
data = outputBuf;
dstFmt = GE_FORMAT_8888;
dstFmt = SCALER_FORMAT_8888;
width *= factor;
height *= factor;
@ -636,24 +636,35 @@ static void convert5551(u16* data, u32* out, int width, int l, int u) {
}
}
void TextureScaler::ConvertTo8888(GEBufferFormat format, u32* source, u32* &dest, int width, int height) {
static void convert1555(u16* data, u32* out, int width, int l, int u) {
for (int y = l; y < u; ++y) {
ConvertARGB1555ToRGBA8888(out + y * width, data + y * width, width);
}
}
void TextureScaler::ConvertTo8888(ScalerPixelFormat format, u32* source, u32* &dest, int width, int height) {
switch(format) {
case GE_FORMAT_8888:
case SCALER_FORMAT_8888:
dest = source; // already fine
break;
case GE_FORMAT_4444:
case SCALER_FORMAT_4444:
GlobalThreadPool::Loop(std::bind(&convert4444, (u16*)source, dest, width, placeholder::_1, placeholder::_2), 0, height);
break;
case GE_FORMAT_565:
case SCALER_FORMAT_565:
GlobalThreadPool::Loop(std::bind(&convert565, (u16*)source, dest, width, placeholder::_1, placeholder::_2), 0, height);
break;
case GE_FORMAT_5551:
case SCALER_FORMAT_5551:
GlobalThreadPool::Loop(std::bind(&convert5551, (u16*)source, dest, width, placeholder::_1, placeholder::_2), 0, height);
break;
case SCALER_FORMAT_1555:
GlobalThreadPool::Loop(std::bind(&convert1555, (u16*)source, dest, width, placeholder::_1, placeholder::_2), 0, height);
break;
default:
dest = source;
ERROR_LOG(G3D, "iXBRZTexScaling: unsupported texture format");

View File

@ -24,11 +24,19 @@
#include <vector>
enum ScalerPixelFormat {
SCALER_FORMAT_8888,
SCALER_FORMAT_565,
SCALER_FORMAT_5551,
SCALER_FORMAT_1555,
SCALER_FORMAT_4444,
};
class TextureScaler {
public:
TextureScaler();
void Scale(u32* &data, GEBufferFormat &dstfmt, int &width, int &height, int factor);
void Scale(u32* &data, ScalerPixelFormat &dstfmt, int &width, int &height, int factor);
enum { XBRZ= 0, HYBRID = 1, BICUBIC = 2, HYBRID_BICUBIC = 3 };
@ -38,7 +46,7 @@ private:
void ScaleBicubicBSpline(int factor, u32* source, u32* dest, int width, int height);
void ScaleBicubicMitchell(int factor, u32* source, u32* dest, int width, int height);
void ScaleHybrid(int factor, u32* source, u32* dest, int width, int height, bool bicubic = false);
void ConvertTo8888(GEBufferFormat format, u32* source, u32* &dest, int width, int height);
void ConvertTo8888(ScalerPixelFormat format, u32* source, u32* &dest, int width, int height);
void DePosterize(u32* source, u32* dest, int width, int height);

View File

@ -1704,21 +1704,17 @@ void TextureCacheDX9::LoadTextureLevel(TexCacheEntry &entry, int level, int maxL
u32 *pixelData = (u32 *)finalBuf;
if (scaleFactor > 1 && (entry.status & TexCacheEntry::STATUS_CHANGE_FREQUENT) == 0) {
GEBufferFormat dstFormat;
ScalerPixelFormat dstFormat;
switch (dstFmt) {
case D3DFMT_A8R8G8B8: dstFormat = GE_FORMAT_8888; break;
case D3DFMT_R5G6B5: dstFormat = GE_FORMAT_565; break;
case D3DFMT_A4R4G4B4: dstFormat = GE_FORMAT_4444; break;
case D3DFMT_A1R5G5B5: dstFormat = GE_FORMAT_5551; break;
case D3DFMT_A8R8G8B8: dstFormat = SCALER_FORMAT_8888; break;
case D3DFMT_R5G6B5: dstFormat = SCALER_FORMAT_565; break;
case D3DFMT_A4R4G4B4: dstFormat = SCALER_FORMAT_4444; break;
case D3DFMT_A1R5G5B5: dstFormat = SCALER_FORMAT_5551; break;
default: goto dontScale;
}
scaler.Scale(pixelData, dstFormat, w, h, scaleFactor);
switch (dstFormat) {
case GE_FORMAT_8888: dstFmt = D3DFMT_A8R8G8B8; break;
case GE_FORMAT_565: dstFmt = D3DFMT_R5G6B5; break;
case GE_FORMAT_4444: dstFmt = D3DFMT_A4R4G4B4; break;
case GE_FORMAT_5551: dstFmt = D3DFMT_A1R5G5B5; break;
}
// The scaler currently always outputs this.
dstFmt = D3DFMT_A8R8G8B8;
dontScale:
;
}

View File

@ -2003,21 +2003,17 @@ void TextureCache::LoadTextureLevel(TexCacheEntry &entry, int level, bool replac
u32 *pixelData = (u32 *)finalBuf;
if (scaleFactor > 1 && (entry.status & TexCacheEntry::STATUS_CHANGE_FREQUENT) == 0) {
GEBufferFormat dstFormat;
ScalerPixelFormat dstFormat;
switch (dstFmt) {
case GL_UNSIGNED_BYTE: dstFormat = GE_FORMAT_8888; break;
case GL_UNSIGNED_SHORT_4_4_4_4: dstFormat = GE_FORMAT_4444; break;
case GL_UNSIGNED_SHORT_5_6_5: dstFormat = GE_FORMAT_565; break;
case GL_UNSIGNED_SHORT_5_5_5_1: dstFormat = GE_FORMAT_5551; break;
case GL_UNSIGNED_BYTE: dstFormat = SCALER_FORMAT_8888; break;
case GL_UNSIGNED_SHORT_4_4_4_4: dstFormat = SCALER_FORMAT_4444; break;
case GL_UNSIGNED_SHORT_5_6_5: dstFormat = SCALER_FORMAT_565; break;
case GL_UNSIGNED_SHORT_5_5_5_1: dstFormat = SCALER_FORMAT_1555; break;
default: goto dontScale;
}
scaler.Scale(pixelData, dstFormat, w, h, scaleFactor);
switch (dstFormat) {
case GE_FORMAT_8888: dstFmt = GL_UNSIGNED_BYTE; break;
case GE_FORMAT_565: dstFmt = GL_UNSIGNED_SHORT_5_6_5; break;
case GE_FORMAT_5551: dstFmt = GL_UNSIGNED_SHORT_5_5_5_1; break;
case GE_FORMAT_4444: dstFmt = GL_UNSIGNED_SHORT_4_4_4_4; break;
}
// The scaler currently always outputs this.
dstFmt = GL_UNSIGNED_BYTE;
dontScale:
;
}