mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-27 07:20:49 +00:00
D3D11: Expand 16-bit texture formats to 32-bit if they are not supported, like on Windows 7. Part of issue #9317
This commit is contained in:
parent
f24b1495ba
commit
0954ecf28c
@ -1033,7 +1033,7 @@ void TextureCacheCommon::DecodeTextureLevel(u8 *out, int outPitch, GETextureForm
|
||||
case GE_CMODE_16BIT_ABGR4444:
|
||||
{
|
||||
const u16 *clut = GetCurrentClut<u16>() + clutSharingOffset;
|
||||
if (clutAlphaLinear_ && mipmapShareClut) {
|
||||
if (clutAlphaLinear_ && mipmapShareClut && !expandTo32bit) {
|
||||
// Here, reverseColors means the CLUT is already reversed.
|
||||
if (reverseColors) {
|
||||
for (int y = 0; y < h; ++y) {
|
||||
@ -1045,8 +1045,26 @@ void TextureCacheCommon::DecodeTextureLevel(u8 *out, int outPitch, GETextureForm
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int y = 0; y < h; ++y) {
|
||||
DeIndexTexture4((u16 *)(out + outPitch * y), texptr + (bufw * y) / 2, w, clut);
|
||||
if (expandTo32bit && !reverseColors) {
|
||||
// We simply expand the CLUT to 32-bit, then we deindex as usual. Probably the fastest way.
|
||||
switch (clutformat) {
|
||||
case GE_CMODE_16BIT_ABGR4444:
|
||||
ConvertRGBA4444ToRGBA8888(expandClut_, clut, 16);
|
||||
break;
|
||||
case GE_CMODE_16BIT_ABGR5551:
|
||||
ConvertRGBA5551ToRGBA8888(expandClut_, clut, 16);
|
||||
break;
|
||||
case GE_CMODE_16BIT_BGR5650:
|
||||
ConvertRGBA565ToRGBA8888(expandClut_, clut, 16);
|
||||
break;
|
||||
}
|
||||
for (int y = 0; y < h; ++y) {
|
||||
DeIndexTexture4((u32 *)(out + outPitch * y), texptr + (bufw * y) / 2, w, expandClut_);
|
||||
}
|
||||
} else {
|
||||
for (int y = 0; y < h; ++y) {
|
||||
DeIndexTexture4((u16 *)(out + outPitch * y), texptr + (bufw * y) / 2, w, clut);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1069,15 +1087,15 @@ void TextureCacheCommon::DecodeTextureLevel(u8 *out, int outPitch, GETextureForm
|
||||
break;
|
||||
|
||||
case GE_TFMT_CLUT8:
|
||||
ReadIndexedTex(out, outPitch, level, texptr, 1, bufw);
|
||||
ReadIndexedTex(out, outPitch, level, texptr, 1, bufw, expandTo32bit);
|
||||
break;
|
||||
|
||||
case GE_TFMT_CLUT16:
|
||||
ReadIndexedTex(out, outPitch, level, texptr, 2, bufw);
|
||||
ReadIndexedTex(out, outPitch, level, texptr, 2, bufw, expandTo32bit);
|
||||
break;
|
||||
|
||||
case GE_TFMT_CLUT32:
|
||||
ReadIndexedTex(out, outPitch, level, texptr, 4, bufw);
|
||||
ReadIndexedTex(out, outPitch, level, texptr, 4, bufw, expandTo32bit);
|
||||
break;
|
||||
|
||||
case GE_TFMT_4444:
|
||||
@ -1089,6 +1107,20 @@ void TextureCacheCommon::DecodeTextureLevel(u8 *out, int outPitch, GETextureForm
|
||||
for (int y = 0; y < h; ++y) {
|
||||
ReverseColors(out + outPitch * y, texptr + bufw * sizeof(u16) * y, format, w, useBGRA);
|
||||
}
|
||||
} else if (expandTo32bit) {
|
||||
for (int y = 0; y < h; ++y) {
|
||||
switch (format) {
|
||||
case GE_CMODE_16BIT_ABGR4444:
|
||||
ConvertRGBA4444ToRGBA8888((u32 *)(out + outPitch * y), (const u16 *)texptr + bufw * y, w);
|
||||
break;
|
||||
case GE_CMODE_16BIT_ABGR5551:
|
||||
ConvertRGBA5551ToRGBA8888((u32 *)(out + outPitch * y), (const u16 *)texptr + bufw * y, w);
|
||||
break;
|
||||
case GE_CMODE_16BIT_BGR5650:
|
||||
ConvertRGBA565ToRGBA8888((u32 *)(out + outPitch * y), (const u16 *)texptr + bufw * y, w);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int y = 0; y < h; ++y) {
|
||||
memcpy(out + outPitch * y, texptr + bufw * sizeof(u16) * y, w * sizeof(u16));
|
||||
@ -1109,6 +1141,20 @@ void TextureCacheCommon::DecodeTextureLevel(u8 *out, int outPitch, GETextureForm
|
||||
for (int y = 0; y < h; ++y) {
|
||||
ReverseColors(out + outPitch * y, unswizzled + bufw * sizeof(u16) * y, format, w, useBGRA);
|
||||
}
|
||||
} else if (expandTo32bit) {
|
||||
for (int y = 0; y < h; ++y) {
|
||||
switch (format) {
|
||||
case GE_CMODE_16BIT_ABGR4444:
|
||||
ConvertRGBA4444ToRGBA8888((u32 *)(out + outPitch * y), (const u16 *)unswizzled + bufw * y, w);
|
||||
break;
|
||||
case GE_CMODE_16BIT_ABGR5551:
|
||||
ConvertRGBA5551ToRGBA8888((u32 *)(out + outPitch * y), (const u16 *)unswizzled + bufw * y, w);
|
||||
break;
|
||||
case GE_CMODE_16BIT_BGR5650:
|
||||
ConvertRGBA565ToRGBA8888((u32 *)(out + outPitch * y), (const u16 *)unswizzled + bufw * y, w);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int y = 0; y < h; ++y) {
|
||||
memcpy(out + outPitch * y, unswizzled + bufw * sizeof(u16) * y, w * sizeof(u16));
|
||||
@ -1223,7 +1269,7 @@ void TextureCacheCommon::DecodeTextureLevel(u8 *out, int outPitch, GETextureForm
|
||||
}
|
||||
}
|
||||
|
||||
void TextureCacheCommon::ReadIndexedTex(u8 *out, int outPitch, int level, const u8 *texptr, int bytesPerIndex, int bufw) {
|
||||
void TextureCacheCommon::ReadIndexedTex(u8 *out, int outPitch, int level, const u8 *texptr, int bytesPerIndex, int bufw, bool expandTo32Bit) {
|
||||
int w = gstate.getTextureWidth(level);
|
||||
int h = gstate.getTextureHeight(level);
|
||||
|
||||
@ -1233,28 +1279,48 @@ void TextureCacheCommon::ReadIndexedTex(u8 *out, int outPitch, int level, const
|
||||
texptr = (u8 *)tmpTexBuf32_.data();
|
||||
}
|
||||
|
||||
switch (gstate.getClutPaletteFormat()) {
|
||||
int palFormat = gstate.getClutPaletteFormat();
|
||||
|
||||
const u16 *clut16 = (const u16 *)clutBuf_;
|
||||
const u32 *clut32 = (const u32 *)clutBuf_;
|
||||
|
||||
if (expandTo32Bit && palFormat != GE_CMODE_32BIT_ABGR8888) {
|
||||
switch (palFormat) {
|
||||
case GE_CMODE_16BIT_ABGR4444:
|
||||
ConvertRGBA4444ToRGBA8888(expandClut_, clut16, 256);
|
||||
break;
|
||||
case GE_CMODE_16BIT_ABGR5551:
|
||||
ConvertRGBA5551ToRGBA8888(expandClut_, clut16, 256);
|
||||
break;
|
||||
case GE_CMODE_16BIT_BGR5650:
|
||||
ConvertRGBA565ToRGBA8888(expandClut_, clut16, 256);
|
||||
break;
|
||||
}
|
||||
clut32 = expandClut_;
|
||||
palFormat = GE_CMODE_32BIT_ABGR8888;
|
||||
}
|
||||
|
||||
switch (palFormat) {
|
||||
case GE_CMODE_16BIT_BGR5650:
|
||||
case GE_CMODE_16BIT_ABGR5551:
|
||||
case GE_CMODE_16BIT_ABGR4444:
|
||||
{
|
||||
const u16 *clut = GetCurrentClut<u16>();
|
||||
switch (bytesPerIndex) {
|
||||
case 1:
|
||||
for (int y = 0; y < h; ++y) {
|
||||
DeIndexTexture((u16 *)(out + outPitch * y), (const u8 *)texptr + bufw * y, w, clut);
|
||||
DeIndexTexture((u16 *)(out + outPitch * y), (const u8 *)texptr + bufw * y, w, clut16);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
for (int y = 0; y < h; ++y) {
|
||||
DeIndexTexture((u16 *)(out + outPitch * y), (const u16_le *)texptr + bufw * y, w, clut);
|
||||
DeIndexTexture((u16 *)(out + outPitch * y), (const u16_le *)texptr + bufw * y, w, clut16);
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
for (int y = 0; y < h; ++y) {
|
||||
DeIndexTexture((u16 *)(out + outPitch * y), (const u32_le *)texptr + bufw * y, w, clut);
|
||||
DeIndexTexture((u16 *)(out + outPitch * y), (const u32_le *)texptr + bufw * y, w, clut16);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1263,23 +1329,22 @@ void TextureCacheCommon::ReadIndexedTex(u8 *out, int outPitch, int level, const
|
||||
|
||||
case GE_CMODE_32BIT_ABGR8888:
|
||||
{
|
||||
const u32 *clut = GetCurrentClut<u32>();
|
||||
switch (bytesPerIndex) {
|
||||
case 1:
|
||||
for (int y = 0; y < h; ++y) {
|
||||
DeIndexTexture((u32 *)(out + outPitch * y), (const u8 *)texptr + bufw * y, w, clut);
|
||||
DeIndexTexture((u32 *)(out + outPitch * y), (const u8 *)texptr + bufw * y, w, clut32);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
for (int y = 0; y < h; ++y) {
|
||||
DeIndexTexture((u32 *)(out + outPitch * y), (const u16_le *)texptr + bufw * y, w, clut);
|
||||
DeIndexTexture((u32 *)(out + outPitch * y), (const u16_le *)texptr + bufw * y, w, clut32);
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
for (int y = 0; y < h; ++y) {
|
||||
DeIndexTexture((u32 *)(out + outPitch * y), (const u32_le *)texptr + bufw * y, w, clut);
|
||||
DeIndexTexture((u32 *)(out + outPitch * y), (const u32_le *)texptr + bufw * y, w, clut32);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -225,9 +225,9 @@ protected:
|
||||
u32 yOffset;
|
||||
};
|
||||
|
||||
void DecodeTextureLevel(u8 *out, int outPitch, GETextureFormat format, GEPaletteFormat clutformat, uint32_t texaddr, int level, int bufw, bool reverseColors, bool useBGRA, bool expandTo32bit);
|
||||
void DecodeTextureLevel(u8 *out, int outPitch, GETextureFormat format, GEPaletteFormat clutformat, uint32_t texaddr, int level, int bufw, bool reverseColors, bool useBGRA, bool expandTo32Bit);
|
||||
void UnswizzleFromMem(u32 *dest, u32 destPitch, const u8 *texptr, u32 bufw, u32 height, u32 bytesPerPixel);
|
||||
void ReadIndexedTex(u8 *out, int outPitch, int level, const u8 *texptr, int bytesPerIndex, int bufw);
|
||||
void ReadIndexedTex(u8 *out, int outPitch, int level, const u8 *texptr, int bytesPerIndex, int bufw, bool expandTo32Bit);
|
||||
|
||||
template <typename T>
|
||||
inline const T *GetCurrentClut() {
|
||||
@ -322,6 +322,8 @@ protected:
|
||||
bool nextNeedsRebuild_;
|
||||
|
||||
bool isBgraBackend_;
|
||||
|
||||
u32 expandClut_[256];
|
||||
};
|
||||
|
||||
inline bool TexCacheEntry::Matches(u16 dim2, u8 format2, u8 maxLevel2) const {
|
||||
|
@ -81,7 +81,7 @@ ID3D11ShaderResourceView *DepalShaderCacheD3D11::GetClutTexture(GEPaletteFormat
|
||||
return oldtex->second->view;
|
||||
}
|
||||
|
||||
DXGI_FORMAT dstFmt = getClutDestFormatD3D11(clutFormat);
|
||||
DXGI_FORMAT dstFmt = GetClutDestFormatD3D11(clutFormat);
|
||||
int texturePixels = clutFormat == GE_CMODE_32BIT_ABGR8888 ? 256 : 512;
|
||||
|
||||
DepalTextureD3D11 *tex = new DepalTextureD3D11();
|
||||
|
@ -146,21 +146,6 @@ void TextureCacheD3D11::InvalidateLastTexture(TexCacheEntry *entry) {
|
||||
}
|
||||
}
|
||||
|
||||
DXGI_FORMAT TextureCacheD3D11::GetClutDestFormatD3D11(GEPaletteFormat format) {
|
||||
switch (format) {
|
||||
case GE_CMODE_16BIT_ABGR4444:
|
||||
return DXGI_FORMAT_B4G4R4A4_UNORM;
|
||||
case GE_CMODE_16BIT_ABGR5551:
|
||||
return DXGI_FORMAT_B5G5R5A1_UNORM;
|
||||
case GE_CMODE_16BIT_BGR5650:
|
||||
return DXGI_FORMAT_B5G6R5_UNORM;
|
||||
case GE_CMODE_32BIT_ABGR8888:
|
||||
return DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
}
|
||||
// Should never be here !
|
||||
return DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
}
|
||||
|
||||
void TextureCacheD3D11::UpdateSamplingParams(TexCacheEntry &entry, SamplerCacheKey &key) {
|
||||
// TODO: Make GetSamplingParams write SamplerCacheKey directly
|
||||
int minFilt;
|
||||
@ -572,13 +557,32 @@ void TextureCacheD3D11::BuildTexture(TexCacheEntry *const entry, bool replaceIma
|
||||
}
|
||||
}
|
||||
|
||||
DXGI_FORMAT GetClutDestFormatD3D11(GEPaletteFormat format) {
|
||||
switch (format) {
|
||||
case GE_CMODE_16BIT_ABGR4444:
|
||||
return DXGI_FORMAT_B4G4R4A4_UNORM;
|
||||
case GE_CMODE_16BIT_ABGR5551:
|
||||
return DXGI_FORMAT_B5G5R5A1_UNORM;
|
||||
case GE_CMODE_16BIT_BGR5650:
|
||||
return DXGI_FORMAT_B5G6R5_UNORM;
|
||||
case GE_CMODE_32BIT_ABGR8888:
|
||||
return DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
}
|
||||
// Should never be here !
|
||||
return DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
}
|
||||
|
||||
DXGI_FORMAT TextureCacheD3D11::GetDestFormat(GETextureFormat format, GEPaletteFormat clutFormat) const {
|
||||
if (!gstate_c.Supports(GPU_SUPPORTS_16BIT_FORMATS)) {
|
||||
return DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
}
|
||||
|
||||
switch (format) {
|
||||
case GE_TFMT_CLUT4:
|
||||
case GE_TFMT_CLUT8:
|
||||
case GE_TFMT_CLUT16:
|
||||
case GE_TFMT_CLUT32:
|
||||
return getClutDestFormatD3D11(clutFormat);
|
||||
return GetClutDestFormatD3D11(clutFormat);
|
||||
case GE_TFMT_4444:
|
||||
return DXGI_FORMAT_B4G4R4A4_UNORM;
|
||||
case GE_TFMT_5551:
|
||||
@ -633,7 +637,7 @@ DXGI_FORMAT ToDXGIFormat(ReplacedTextureFormat fmt) {
|
||||
}
|
||||
}
|
||||
|
||||
void TextureCacheD3D11::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &replaced, int level, int maxLevel, bool replaceImages, int scaleFactor, u32 dstFmt) {
|
||||
void TextureCacheD3D11::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &replaced, int level, int maxLevel, bool replaceImages, int scaleFactor, DXGI_FORMAT dstFmt) {
|
||||
int w = gstate.getTextureWidth(level);
|
||||
int h = gstate.getTextureHeight(level);
|
||||
|
||||
@ -642,14 +646,13 @@ void TextureCacheD3D11::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &
|
||||
// Create texture
|
||||
int levels = scaleFactor == 1 ? maxLevel + 1 : 1;
|
||||
int tw = w, th = h;
|
||||
DXGI_FORMAT tfmt = (DXGI_FORMAT)(dstFmt);
|
||||
if (replaced.GetSize(level, tw, th)) {
|
||||
tfmt = ToDXGIFormat(replaced.Format(level));
|
||||
dstFmt = ToDXGIFormat(replaced.Format(level));
|
||||
} else {
|
||||
tw *= scaleFactor;
|
||||
th *= scaleFactor;
|
||||
if (scaleFactor > 1) {
|
||||
tfmt = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
dstFmt = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
}
|
||||
}
|
||||
|
||||
@ -661,7 +664,7 @@ void TextureCacheD3D11::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.Width = tw;
|
||||
desc.Height = th;
|
||||
desc.Format = tfmt;
|
||||
desc.Format = dstFmt;
|
||||
desc.MipLevels = levels;
|
||||
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
|
||||
@ -708,10 +711,12 @@ void TextureCacheD3D11::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &
|
||||
decPitch = mapRowPitch;
|
||||
}
|
||||
|
||||
DecodeTextureLevel((u8 *)pixelData, decPitch, tfmt, clutformat, texaddr, level, bufw, false, false, false);
|
||||
bool expand32 = !gstate_c.Supports(GPU_SUPPORTS_16BIT_FORMATS);
|
||||
DecodeTextureLevel((u8 *)pixelData, decPitch, tfmt, clutformat, texaddr, level, bufw, false, false, expand32);
|
||||
|
||||
if (scaleFactor > 1) {
|
||||
scaler.ScaleAlways((u32 *)mapData, pixelData, dstFmt, w, h, scaleFactor);
|
||||
u32 scaleFmt = (u32)dstFmt;
|
||||
scaler.ScaleAlways((u32 *)mapData, pixelData, scaleFmt, w, h, scaleFactor);
|
||||
pixelData = (u32 *)mapData;
|
||||
|
||||
// We always end up at 8888. Other parts assume this.
|
||||
|
@ -71,7 +71,7 @@ protected:
|
||||
|
||||
private:
|
||||
void UpdateSamplingParams(TexCacheEntry &entry, SamplerCacheKey &key);
|
||||
void LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &replaced, int level, int maxLevel, bool replaceImages, int scaleFactor, u32 dstFmt);
|
||||
void LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &replaced, int level, int maxLevel, bool replaceImages, int scaleFactor, DXGI_FORMAT dstFmt);
|
||||
DXGI_FORMAT GetDestFormat(GETextureFormat format, GEPaletteFormat clutFormat) const;
|
||||
TexCacheEntry::Status CheckAlpha(const u32 *pixelData, u32 dstFmt, int stride, int w, int h);
|
||||
void UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBase, bool clutIndexIsSimple) override;
|
||||
@ -79,8 +79,6 @@ private:
|
||||
void ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer) override;
|
||||
void BuildTexture(TexCacheEntry *const entry, bool replaceImages) override;
|
||||
|
||||
DXGI_FORMAT GetClutDestFormatD3D11(GEPaletteFormat format);
|
||||
|
||||
ID3D11Device *device_;
|
||||
ID3D11DeviceContext *context_;
|
||||
|
||||
@ -106,4 +104,4 @@ private:
|
||||
ShaderManagerD3D11 *shaderManager_;
|
||||
};
|
||||
|
||||
DXGI_FORMAT getClutDestFormatD3D11(GEPaletteFormat format);
|
||||
DXGI_FORMAT GetClutDestFormatD3D11(GEPaletteFormat format);
|
||||
|
Loading…
Reference in New Issue
Block a user