From 58c2ba987d7ef033fb5d744737ecb364eab3c2d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 17 Mar 2017 10:11:17 +0100 Subject: [PATCH 1/2] D3D11: Expand 16-bit CLUT textures to 32-bit if not supported. --- GPU/D3D11/DepalettizeShaderD3D11.cpp | 34 ++++++++++++++++++++++++---- GPU/D3D11/DepalettizeShaderD3D11.h | 2 +- GPU/D3D11/TextureCacheD3D11.cpp | 3 ++- 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/GPU/D3D11/DepalettizeShaderD3D11.cpp b/GPU/D3D11/DepalettizeShaderD3D11.cpp index f0833cdfd..cf454e4c7 100644 --- a/GPU/D3D11/DepalettizeShaderD3D11.cpp +++ b/GPU/D3D11/DepalettizeShaderD3D11.cpp @@ -21,6 +21,7 @@ #include "base/basictypes.h" #include "base/logging.h" #include "Common/Log.h" +#include "Common/ColorConv.h" #include "Core/Reporting.h" #include "GPU/D3D11/TextureCacheD3D11.h" #include "GPU/D3D11/DepalettizeShaderD3D11.h" @@ -74,7 +75,7 @@ u32 DepalShaderCacheD3D11::GenerateShaderID(GEPaletteFormat clutFormat, GEBuffer return (clutFormat & 0xFFFFFF) | (pixelFormat << 24); } -ID3D11ShaderResourceView *DepalShaderCacheD3D11::GetClutTexture(GEPaletteFormat clutFormat, const u32 clutID, u32 *rawClut) { +ID3D11ShaderResourceView *DepalShaderCacheD3D11::GetClutTexture(GEPaletteFormat clutFormat, const u32 clutID, u32 *rawClut, bool expandTo32bit) { const u32 realClutID = clutID ^ clutFormat; auto oldtex = texCache_.find(realClutID); @@ -83,11 +84,29 @@ ID3D11ShaderResourceView *DepalShaderCacheD3D11::GetClutTexture(GEPaletteFormat return oldtex->second->view; } - DXGI_FORMAT dstFmt = GetClutDestFormatD3D11(clutFormat); int texturePixels = clutFormat == GE_CMODE_32BIT_ABGR8888 ? 256 : 512; - DepalTextureD3D11 *tex = new DepalTextureD3D11(); - // TODO: Look into 1D textures + DXGI_FORMAT dstFmt; + uint32_t *expanded = nullptr; + if (expandTo32bit && clutFormat != GE_CMODE_32BIT_ABGR8888) { + expanded = new uint32_t[texturePixels]; + switch (clutFormat) { + case GE_CMODE_16BIT_ABGR4444: + ConvertRGBA4444ToRGBA8888(expanded, (const uint16_t *)rawClut, texturePixels); + break; + case GE_CMODE_16BIT_ABGR5551: + ConvertRGBA5551ToRGBA8888(expanded, (const uint16_t *)rawClut, texturePixels); + break; + case GE_CMODE_16BIT_BGR5650: + ConvertRGBA565ToRGBA8888(expanded, (const uint16_t *)rawClut, texturePixels); + break; + } + rawClut = expanded; + dstFmt = DXGI_FORMAT_B8G8R8A8_UNORM; + } + else { + dstFmt = GetClutDestFormatD3D11(clutFormat); + } D3D11_TEXTURE2D_DESC desc{}; desc.Width = texturePixels; @@ -103,10 +122,17 @@ ID3D11ShaderResourceView *DepalShaderCacheD3D11::GetClutTexture(GEPaletteFormat data.pSysMem = rawClut; // Regardless of format, the CLUT should always be 1024 bytes. data.SysMemPitch = 1024; + + DepalTextureD3D11 *tex = new DepalTextureD3D11(); + // TODO: Look into 1D textures ASSERT_SUCCESS(device_->CreateTexture2D(&desc, &data, &tex->texture)); ASSERT_SUCCESS(device_->CreateShaderResourceView(tex->texture, nullptr, &tex->view)); tex->lastFrame = gpuStats.numFlips; texCache_[realClutID] = tex; + + if (expandTo32bit) { + delete[] expanded; + } return tex->view; } diff --git a/GPU/D3D11/DepalettizeShaderD3D11.h b/GPU/D3D11/DepalettizeShaderD3D11.h index 7fdc0a620..3d1b92f85 100644 --- a/GPU/D3D11/DepalettizeShaderD3D11.h +++ b/GPU/D3D11/DepalettizeShaderD3D11.h @@ -52,7 +52,7 @@ public: ID3D11PixelShader *GetDepalettizePixelShader(GEPaletteFormat clutFormat, GEBufferFormat pixelFormat); ID3D11VertexShader *GetDepalettizeVertexShader() { return vertexShader_; } ID3D11InputLayout *GetInputLayout() { return inputLayout_; } - ID3D11ShaderResourceView *GetClutTexture(GEPaletteFormat clutFormat, const u32 clutHash, u32 *rawClut); + ID3D11ShaderResourceView *GetClutTexture(GEPaletteFormat clutFormat, const u32 clutHash, u32 *rawClut, bool expandTo32bit); void Clear(); void Decimate(); diff --git a/GPU/D3D11/TextureCacheD3D11.cpp b/GPU/D3D11/TextureCacheD3D11.cpp index d0021e043..de6d240bd 100644 --- a/GPU/D3D11/TextureCacheD3D11.cpp +++ b/GPU/D3D11/TextureCacheD3D11.cpp @@ -396,7 +396,8 @@ void TextureCacheD3D11::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFra } if (pshader) { - ID3D11ShaderResourceView *clutTexture = depalShaderCache_->GetClutTexture(clutFormat, clutHash_, clutBuf_); + bool expand32 = !gstate_c.Supports(GPU_SUPPORTS_16BIT_FORMATS); + ID3D11ShaderResourceView *clutTexture = depalShaderCache_->GetClutTexture(clutFormat, clutHash_, clutBuf_, expand32); Draw::Framebuffer *depalFBO = framebufferManagerD3D11_->GetTempFBO(framebuffer->renderWidth, framebuffer->renderHeight, Draw::FBO_8888); shaderManager_->DirtyLastShader(); From 5d613bf565a4099f2a94e6bdcbaf9b18786d301c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 17 Mar 2017 16:56:45 +0100 Subject: [PATCH 2/2] Set pitch correctly when uploading converted CLUT textures --- GPU/D3D11/DepalettizeShaderD3D11.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/GPU/D3D11/DepalettizeShaderD3D11.cpp b/GPU/D3D11/DepalettizeShaderD3D11.cpp index cf454e4c7..a0d9e7dff 100644 --- a/GPU/D3D11/DepalettizeShaderD3D11.cpp +++ b/GPU/D3D11/DepalettizeShaderD3D11.cpp @@ -85,7 +85,7 @@ ID3D11ShaderResourceView *DepalShaderCacheD3D11::GetClutTexture(GEPaletteFormat } int texturePixels = clutFormat == GE_CMODE_32BIT_ABGR8888 ? 256 : 512; - + int bpp = clutFormat == GE_CMODE_32BIT_ABGR8888 ? 4 : 2; DXGI_FORMAT dstFmt; uint32_t *expanded = nullptr; if (expandTo32bit && clutFormat != GE_CMODE_32BIT_ABGR8888) { @@ -103,6 +103,7 @@ ID3D11ShaderResourceView *DepalShaderCacheD3D11::GetClutTexture(GEPaletteFormat } rawClut = expanded; dstFmt = DXGI_FORMAT_B8G8R8A8_UNORM; + bpp = 4; } else { dstFmt = GetClutDestFormatD3D11(clutFormat); @@ -121,7 +122,7 @@ ID3D11ShaderResourceView *DepalShaderCacheD3D11::GetClutTexture(GEPaletteFormat D3D11_SUBRESOURCE_DATA data{}; data.pSysMem = rawClut; // Regardless of format, the CLUT should always be 1024 bytes. - data.SysMemPitch = 1024; + data.SysMemPitch = texturePixels * bpp; DepalTextureD3D11 *tex = new DepalTextureD3D11(); // TODO: Look into 1D textures