From e345a6ba3c971e35d199693a70072ae58e3967c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 5 Aug 2022 12:34:29 +0200 Subject: [PATCH] Works with D3D11, except the depth texturing case --- CMakeLists.txt | 2 - GPU/Common/DepalettizeCommon.cpp | 3 + GPU/Common/DepalettizeCommon.h | 2 + GPU/Common/TextureCacheCommon.h | 1 + GPU/D3D11/DepalettizeShaderD3D11.cpp | 213 ------------------------- GPU/D3D11/DepalettizeShaderD3D11.h | 72 --------- GPU/D3D11/GPU_D3D11.cpp | 2 +- GPU/D3D11/GPU_D3D11.h | 4 +- GPU/D3D11/TextureCacheD3D11.cpp | 229 +++++++++------------------ GPU/D3D11/TextureCacheD3D11.h | 7 +- GPU/GLES/TextureCacheGLES.h | 2 +- GPU/GPU.vcxproj | 2 - GPU/GPU.vcxproj.filters | 6 - GPU/Vulkan/TextureCacheVulkan.cpp | 4 + GPU/Vulkan/TextureCacheVulkan.h | 1 + UWP/GPU_UWP/GPU_UWP.vcxproj | 2 - UWP/GPU_UWP/GPU_UWP.vcxproj.filters | 2 - libretro/Makefile.common | 1 - 18 files changed, 90 insertions(+), 465 deletions(-) delete mode 100644 GPU/D3D11/DepalettizeShaderD3D11.cpp delete mode 100644 GPU/D3D11/DepalettizeShaderD3D11.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 899cdb6c0e..c4852348df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1500,8 +1500,6 @@ set(GPU_D3D9 ) set(GPU_D3D11 - GPU/D3D11/DepalettizeShaderD3D11.cpp - GPU/D3D11/DepalettizeShaderD3D11.h GPU/D3D11/DrawEngineD3D11.cpp GPU/D3D11/DrawEngineD3D11.h GPU/D3D11/FramebufferManagerD3D11.cpp diff --git a/GPU/Common/DepalettizeCommon.cpp b/GPU/Common/DepalettizeCommon.cpp index 5d3f0fbb25..8f565ea3e6 100644 --- a/GPU/Common/DepalettizeCommon.cpp +++ b/GPU/Common/DepalettizeCommon.cpp @@ -61,6 +61,9 @@ bool DepalShaderCache::GenerateVertexShader(char *buffer, const ShaderLanguageDe writer.BeginVSMain(vsInputs, Slice::empty(), varyings); writer.C(" v_texcoord0 = a_texcoord0;\n"); writer.C(" gl_Position = vec4(a_position, 0.0, 1.0);\n"); + if (strlen(lang.viewportYSign)) { + writer.F(" gl_Position.y *= %s1.0;\n", lang.viewportYSign); + } writer.EndVSMain(varyings); return true; } diff --git a/GPU/Common/DepalettizeCommon.h b/GPU/Common/DepalettizeCommon.h index dfdd775fc2..79c53de85c 100644 --- a/GPU/Common/DepalettizeCommon.h +++ b/GPU/Common/DepalettizeCommon.h @@ -15,6 +15,8 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#pragma once + #include #include #include diff --git a/GPU/Common/TextureCacheCommon.h b/GPU/Common/TextureCacheCommon.h index a2270920ca..8d8a35e97e 100644 --- a/GPU/Common/TextureCacheCommon.h +++ b/GPU/Common/TextureCacheCommon.h @@ -297,6 +297,7 @@ public: virtual void InvalidateLastTexture() = 0; virtual void Clear(bool delete_them); virtual void NotifyConfigChanged(); + virtual void ApplySamplingParams(const SamplerCacheKey &key) = 0; // FramebufferManager keeps TextureCache updated about what regions of memory are being rendered to, // so that it can invalidate TexCacheEntries pointed at those addresses. diff --git a/GPU/D3D11/DepalettizeShaderD3D11.cpp b/GPU/D3D11/DepalettizeShaderD3D11.cpp deleted file mode 100644 index 05e8621d47..0000000000 --- a/GPU/D3D11/DepalettizeShaderD3D11.cpp +++ /dev/null @@ -1,213 +0,0 @@ -// Copyright (c) 2014- PPSSPP Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0 or later versions. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official git repository and contact information can be found at -// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. - -#include -#include - -#include "Common/CommonTypes.h" -#include "Common/Data/Convert/ColorConv.h" -#include "Common/Log.h" -#include "Common/StringUtils.h" -#include "Core/Reporting.h" -#include "GPU/D3D11/TextureCacheD3D11.h" -#include "GPU/D3D11/DepalettizeShaderD3D11.h" -#include "GPU/D3D11/D3D11Util.h" -#include "GPU/Common/DepalettizeShaderCommon.h" - -#ifdef _WIN32 -#define SHADERLOG -#endif - -static const char *depalVShaderHLSL = R"( -struct VS_IN { - float3 a_position : POSITION; - float2 a_texcoord0 : TEXCOORD0; -}; -struct VS_OUT { - float2 Texcoord : TEXCOORD0; - float4 Position : SV_Position; -}; -VS_OUT main(VS_IN input) { - VS_OUT output; - output.Texcoord = input.a_texcoord0; - output.Position = float4(input.a_position, 1.0); - return output; -} -)"; - -static const D3D11_INPUT_ELEMENT_DESC g_DepalVertexElements[] = { - { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, }, - { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, }, -}; - -DepalShaderCacheD3D11::DepalShaderCacheD3D11(Draw::DrawContext *draw) { - std::string errorMessage; - std::vector vsByteCode; - device_ = (ID3D11Device *)draw->GetNativeObject(Draw::NativeObject::DEVICE); - context_ = (ID3D11DeviceContext *)draw->GetNativeObject(Draw::NativeObject::CONTEXT); - featureLevel_ = (D3D_FEATURE_LEVEL)draw->GetNativeObject(Draw::NativeObject::FEATURE_LEVEL); - vertexShader_ = CreateVertexShaderD3D11(device_, depalVShaderHLSL, strlen(depalVShaderHLSL), &vsByteCode, featureLevel_); - ASSERT_SUCCESS(device_->CreateInputLayout(g_DepalVertexElements, ARRAY_SIZE(g_DepalVertexElements), vsByteCode.data(), vsByteCode.size(), &inputLayout_)); -} - -DepalShaderCacheD3D11::~DepalShaderCacheD3D11() { - Clear(); - vertexShader_->Release(); - inputLayout_->Release(); -} - -ID3D11ShaderResourceView *DepalShaderCacheD3D11::GetClutTexture(GEPaletteFormat clutFormat, const u32 clutHash, u32 *rawClut, bool expandTo32bit) { - const u32 clutId = GetClutID(clutFormat, clutHash); - - auto oldtex = texCache_.find(clutId); - if (oldtex != texCache_.end()) { - oldtex->second->lastFrame = gpuStats.numFlips; - return oldtex->second->view; - } - - 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) { - 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: - ConvertRGB565ToRGBA8888(expanded, (const uint16_t *)rawClut, texturePixels); - break; - } - rawClut = expanded; - dstFmt = DXGI_FORMAT_B8G8R8A8_UNORM; - bpp = 4; - } - else { - dstFmt = GetClutDestFormatD3D11(clutFormat); - } - - D3D11_TEXTURE2D_DESC desc{}; - desc.Width = texturePixels; - desc.Height = 1; - desc.ArraySize = 1; - desc.MipLevels = 1; - desc.Format = dstFmt; - desc.SampleDesc.Count = 1; - desc.Usage = D3D11_USAGE_IMMUTABLE; - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - - D3D11_SUBRESOURCE_DATA data{}; - data.pSysMem = rawClut; - // Regardless of format, the CLUT should always be 1024 bytes. - data.SysMemPitch = texturePixels * bpp; - - 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_[clutId] = tex; - - if (expandTo32bit) { - delete[] expanded; - } - return tex->view; -} - -void DepalShaderCacheD3D11::Clear() { - for (auto shader = cache_.begin(); shader != cache_.end(); ++shader) { - shader->second->pixelShader->Release(); - delete shader->second; - } - cache_.clear(); - - for (auto tex = texCache_.begin(); tex != texCache_.end(); ++tex) { - delete tex->second; - } - texCache_.clear(); -} - -void DepalShaderCacheD3D11::Decimate() { - for (auto tex = texCache_.begin(); tex != texCache_.end();) { - if (tex->second->lastFrame + DEPAL_TEXTURE_OLD_AGE < gpuStats.numFlips) { - delete tex->second; - texCache_.erase(tex++); - } else { - ++tex; - } - } -} - -ID3D11PixelShader *DepalShaderCacheD3D11::GetDepalettizePixelShader(uint32_t clutMode, GEBufferFormat pixelFormat) { - u32 id = GenerateShaderID(clutMode, pixelFormat); - - auto shader = cache_.find(id); - if (shader != cache_.end()) { - return shader->second->pixelShader; - } - - char *buffer = new char[2048]; - - GenerateDepalShader(buffer, pixelFormat, HLSL_D3D11); - - ID3D11PixelShader *pshader = CreatePixelShaderD3D11(device_, buffer, strlen(buffer), featureLevel_); - - if (!pshader) { - ERROR_LOG(G3D, "Failed to compile depal pixel shader"); - delete[] buffer; - return nullptr; - } - - DepalShaderD3D11 *depal = new DepalShaderD3D11(); - depal->pixelShader = pshader; - depal->code = buffer; - - cache_[id] = depal; - - - delete[] buffer; - - return depal->pixelShader; -} - -std::vector DepalShaderCacheD3D11::DebugGetShaderIDs(DebugShaderType type) { - std::vector ids; - for (auto &iter : cache_) { - ids.push_back(StringFromFormat("%08x", iter.first)); - } - return ids; -} - -std::string DepalShaderCacheD3D11::DebugGetShaderString(std::string idstr, DebugShaderType type, DebugShaderStringType stringType) { - uint32_t id; - sscanf(idstr.c_str(), "%08x", &id); - auto iter = cache_.find(id); - if (iter == cache_.end()) - return ""; - switch (stringType) { - case SHADER_STRING_SHORT_DESC: - return idstr; - case SHADER_STRING_SOURCE_CODE: - return iter->second->code; - default: - return ""; - } -} diff --git a/GPU/D3D11/DepalettizeShaderD3D11.h b/GPU/D3D11/DepalettizeShaderD3D11.h deleted file mode 100644 index 0941330fa6..0000000000 --- a/GPU/D3D11/DepalettizeShaderD3D11.h +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) 2017- PPSSPP Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0 or later versions. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official git repository and contact information can be found at -// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. - -#include -#include -#include -#include - -#include "Common/CommonTypes.h" -#include "GPU/ge_constants.h" -#include "Common/GPU/thin3d.h" -#include "GPU/Common/DepalettizeShaderCommon.h" - -class DepalShaderD3D11 { -public: - ID3D11PixelShader *pixelShader; - std::string code; -}; - -class DepalTextureD3D11 { -public: - ~DepalTextureD3D11() { - if (texture) - texture->Release(); - if (view) - view->Release(); - } - ID3D11Texture2D *texture; - ID3D11ShaderResourceView *view; - int lastFrame; -}; - -// Caches both shaders and palette textures. -class DepalShaderCacheD3D11 : public DepalShaderCacheCommon { -public: - DepalShaderCacheD3D11(Draw::DrawContext *draw); - ~DepalShaderCacheD3D11(); - - // This also uploads the palette and binds the correct texture. - ID3D11PixelShader *GetDepalettizePixelShader(uint32_t clutMode, GEBufferFormat pixelFormat); - ID3D11VertexShader *GetDepalettizeVertexShader() { return vertexShader_; } - ID3D11InputLayout *GetInputLayout() { return inputLayout_; } - ID3D11ShaderResourceView *GetClutTexture(GEPaletteFormat clutFormat, const u32 clutHash, u32 *rawClut, bool expandTo32bit); - void Clear(); - void Decimate(); - std::vector DebugGetShaderIDs(DebugShaderType type); - std::string DebugGetShaderString(std::string id, DebugShaderType type, DebugShaderStringType stringType); - -private: - ID3D11Device *device_; - ID3D11DeviceContext *context_; - D3D_FEATURE_LEVEL featureLevel_; - ID3D11VertexShader *vertexShader_ = nullptr; - ID3D11InputLayout *inputLayout_ = nullptr; - - std::map cache_; - std::map texCache_; -}; diff --git a/GPU/D3D11/GPU_D3D11.cpp b/GPU/D3D11/GPU_D3D11.cpp index ba68c1bd4d..34c63a91af 100644 --- a/GPU/D3D11/GPU_D3D11.cpp +++ b/GPU/D3D11/GPU_D3D11.cpp @@ -64,7 +64,7 @@ GPU_D3D11::GPU_D3D11(GraphicsContext *gfxCtx, Draw::DrawContext *draw) textureCache_ = textureCacheD3D11_; drawEngineCommon_ = &drawEngine_; shaderManager_ = shaderManagerD3D11_; - depalShaderCache_ = new DepalShaderCacheD3D11(draw); + depalShaderCache_ = new DepalShaderCache(draw); drawEngine_.SetShaderManager(shaderManagerD3D11_); drawEngine_.SetTextureCache(textureCacheD3D11_); drawEngine_.SetFramebufferManager(framebufferManagerD3D11_); diff --git a/GPU/D3D11/GPU_D3D11.h b/GPU/D3D11/GPU_D3D11.h index bf41243b88..db5bb05e16 100644 --- a/GPU/D3D11/GPU_D3D11.h +++ b/GPU/D3D11/GPU_D3D11.h @@ -23,7 +23,7 @@ #include "GPU/GPUCommon.h" #include "GPU/D3D11/DrawEngineD3D11.h" -#include "GPU/D3D11/DepalettizeShaderD3D11.h" +#include "GPU/Common/DepalettizeCommon.h" #include "GPU/Common/VertexDecoderCommon.h" class FramebufferManagerD3D11; @@ -78,7 +78,7 @@ private: FramebufferManagerD3D11 *framebufferManagerD3D11_; TextureCacheD3D11 *textureCacheD3D11_; - DepalShaderCacheD3D11 *depalShaderCache_; + DepalShaderCache *depalShaderCache_; DrawEngineD3D11 drawEngine_; ShaderManagerD3D11 *shaderManagerD3D11_; }; diff --git a/GPU/D3D11/TextureCacheD3D11.cpp b/GPU/D3D11/TextureCacheD3D11.cpp index a1aaccb80e..796073bb0c 100644 --- a/GPU/D3D11/TextureCacheD3D11.cpp +++ b/GPU/D3D11/TextureCacheD3D11.cpp @@ -31,7 +31,7 @@ #include "GPU/D3D11/TextureCacheD3D11.h" #include "GPU/D3D11/FramebufferManagerD3D11.h" #include "GPU/D3D11/ShaderManagerD3D11.h" -#include "GPU/D3D11/DepalettizeShaderD3D11.h" +#include "GPU/Common/DepalettizeCommon.h" #include "GPU/D3D11/D3D11Util.h" #include "GPU/Common/FramebufferManagerCommon.h" #include "GPU/Common/TextureDecoder.h" @@ -245,6 +245,11 @@ void TextureCacheD3D11::BindTexture(TexCacheEntry *entry) { context_->PSSetSamplers(0, 1, &state); } +void TextureCacheD3D11::ApplySamplingParams(const SamplerCacheKey &key) { + ID3D11SamplerState *state = samplerCache_.GetOrCreateSampler(device_, key); + context_->PSSetSamplers(0, 1, &state); +} + void TextureCacheD3D11::Unbind() { ID3D11ShaderResourceView *nullView = nullptr; context_->PSSetShaderResources(0, 1, &nullView); @@ -257,188 +262,96 @@ void TextureCacheD3D11::BindAsClutTexture(Draw::Texture *tex) { context_->PSSetSamplers(3, 1, &stockD3D11.samplerPoint2DWrap); } -class TextureShaderApplierD3D11 { -public: - struct Pos { - Pos(float x_, float y_, float z_) : x(x_), y(y_), z(z_) { - } - Pos() { - } - - float x; - float y; - float z; - }; - struct UV { - UV(float u_, float v_) : u(u_), v(v_) { - } - UV() { - } - - float u; - float v; - }; - - struct PosUV { - Pos pos; - UV uv; - }; - - TextureShaderApplierD3D11(ID3D11DeviceContext *context, ID3D11PixelShader *pshader, ID3D11Buffer *dynamicBuffer, float bufferW, float bufferH, int renderW, int renderH, float xoff, float yoff) - : context_(context), pshader_(pshader), vbuffer_(dynamicBuffer), bufferW_(bufferW), bufferH_(bufferH), renderW_(renderW), renderH_(renderH) { - static const Pos pos[4] = { - { -1, 1, 0 }, - { 1, 1, 0 }, - { -1, -1, 0 }, - { 1, -1, 0 }, - }; - static const UV uv[4] = { - { 0, 0 }, - { 1, 0 }, - { 0, 1 }, - { 1, 1 }, - }; - - for (int i = 0; i < 4; ++i) { - verts_[i].pos = pos[i]; - verts_[i].pos.x += xoff; - verts_[i].pos.y += yoff; - verts_[i].uv = uv[i]; - } - } - - void ApplyBounds(const KnownVertexBounds &bounds, u32 uoff, u32 voff, float xoff, float yoff) { - // If min is not < max, then we don't have values (wasn't set during decode.) - if (bounds.minV < bounds.maxV) { - const float invWidth = 1.0f / bufferW_; - const float invHeight = 1.0f / bufferH_; - // Inverse of half = double. - const float invHalfWidth = invWidth * 2.0f; - const float invHalfHeight = invHeight * 2.0f; - - const int u1 = bounds.minU + uoff; - const int v1 = bounds.minV + voff; - const int u2 = bounds.maxU + uoff; - const int v2 = bounds.maxV + voff; - - const float left = u1 * invHalfWidth - 1.0f + xoff; - const float right = u2 * invHalfWidth - 1.0f + xoff; - const float top = (bufferH_ - v1) * invHalfHeight - 1.0f + yoff; - const float bottom = (bufferH_ - v2) * invHalfHeight - 1.0f + yoff; - - float z = 0.0f; - verts_[0].pos = Pos(left, top, z); - verts_[1].pos = Pos(right, top, z); - verts_[2].pos = Pos(left, bottom, z); - verts_[3].pos = Pos(right, bottom, z); - - // And also the UVs, same order. - const float uvleft = u1 * invWidth; - const float uvright = u2 * invWidth; - const float uvtop = v1 * invHeight; - const float uvbottom = v2 * invHeight; - - verts_[0].uv = UV(uvleft, uvtop); - verts_[1].uv = UV(uvright, uvtop); - verts_[2].uv = UV(uvleft, uvbottom); - verts_[3].uv = UV(uvright, uvbottom); - - // We need to reapply the texture next time since we cropped UV. - gstate_c.Dirty(DIRTY_TEXTURE_PARAMS); - } - - D3D11_MAPPED_SUBRESOURCE map; - context_->Map(vbuffer_, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); - memcpy(map.pData, &verts_[0], 4 * 5 * sizeof(float)); - context_->Unmap(vbuffer_, 0); - } - - void Use(ID3D11VertexShader *vshader, ID3D11InputLayout *decl) { - context_->PSSetShader(pshader_, 0, 0); - context_->VSSetShader(vshader, 0, 0); - context_->IASetInputLayout(decl); - } - - void Shade() { - D3D11_VIEWPORT vp{ 0.0f, 0.0f, (float)renderW_, (float)renderH_, 0.0f, 1.0f }; - context_->OMSetBlendState(stockD3D11.blendStateDisabledWithColorMask[0xF], nullptr, 0xFFFFFFFF); - context_->OMSetDepthStencilState(stockD3D11.depthStencilDisabled, 0xFF); - context_->RSSetState(stockD3D11.rasterStateNoCull); - context_->RSSetViewports(1, &vp); - context_->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - context_->IASetVertexBuffers(0, 1, &vbuffer_, &stride_, &offset_); - context_->Draw(4, 0); - gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE | DIRTY_VIEWPORTSCISSOR_STATE); - } - -protected: - ID3D11DeviceContext *context_; - ID3D11PixelShader *pshader_; - ID3D11Buffer *vbuffer_; - PosUV verts_[4]; - UINT stride_ = sizeof(PosUV); - UINT offset_ = 0; - float bufferW_; - float bufferH_; - int renderW_; - int renderH_; -}; - void TextureCacheD3D11::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer, GETextureFormat texFormat, FramebufferNotificationChannel channel) { - ID3D11PixelShader *pshader = nullptr; + DepalShader *depalShader = nullptr; uint32_t clutMode = gstate.clutformat & 0xFFFFFF; bool need_depalettize = IsClutFormat(texFormat); + bool depth = channel == NOTIFY_FB_DEPTH; - if (need_depalettize && !g_Config.bDisableSlowFramebufEffects) { - pshader = depalShaderCache_->GetDepalettizePixelShader(clutMode, depth ? GE_FORMAT_DEPTH16 : framebuffer->drawnFormat); + bool useShaderDepal = framebufferManager_->GetCurrentRenderVFB() != framebuffer && (gstate_c.Supports(GPU_SUPPORTS_GLSL_ES_300) || gstate_c.Supports(GPU_SUPPORTS_GLSL_330)) && !depth; + if (!gstate_c.Supports(GPU_SUPPORTS_32BIT_INT_FSHADER)) { + useShaderDepal = false; + depth = false; // Can't support this } - if (pshader) { - bool expand32 = !gstate_c.Supports(GPU_SUPPORTS_16BIT_FORMATS); + if (need_depalettize && !g_Config.bDisableSlowFramebufEffects) { + if (useShaderDepal) { + const GEPaletteFormat clutFormat = gstate.getClutPaletteFormat(); + + // Very icky conflation here of native and thin3d rendering. This will need careful work per backend in BindAsClutTexture. + Draw::Texture *clutTexture = depalShaderCache_->GetClutTexture(clutFormat, clutHash_, clutBufRaw_); + BindAsClutTexture(clutTexture); + + framebufferManager_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_MAY_COPY_WITH_UV | BINDFBCOLOR_APPLY_TEX_OFFSET); + SamplerCacheKey samplerKey = GetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight); + samplerKey.magFilt = false; + samplerKey.minFilt = false; + samplerKey.mipEnable = false; + ApplySamplingParams(samplerKey); + + // Since we started/ended render passes, might need these. + gstate_c.Dirty(DIRTY_DEPAL); + gstate_c.SetUseShaderDepal(true); + gstate_c.depalFramebufferFormat = framebuffer->drawnFormat; + const u32 bytesPerColor = clutFormat == GE_CMODE_32BIT_ABGR8888 ? sizeof(u32) : sizeof(u16); + const u32 clutTotalColors = clutMaxBytes_ / bytesPerColor; + CheckAlphaResult alphaStatus = CheckCLUTAlpha((const uint8_t *)clutBuf_, clutFormat, clutTotalColors); + gstate_c.SetTextureFullAlpha(alphaStatus == CHECKALPHA_FULL); + + draw_->InvalidateCachedState(); + InvalidateLastTexture(); + return; + } + + depalShader = depalShaderCache_->GetDepalettizeShader(clutMode, depth ? GE_FORMAT_DEPTH16 : framebuffer->drawnFormat); + gstate_c.SetUseShaderDepal(false); + } + + if (depalShader) { const GEPaletteFormat clutFormat = gstate.getClutPaletteFormat(); - ID3D11ShaderResourceView *clutTexture = depalShaderCache_->GetClutTexture(clutFormat, clutHash_, clutBuf_, expand32); + Draw::Texture *clutTexture = depalShaderCache_->GetClutTexture(clutFormat, clutHash_, clutBufRaw_); + Draw::Framebuffer *depalFBO = framebufferManager_->GetTempFBO(TempFBO::DEPAL, framebuffer->renderWidth, framebuffer->renderHeight); + draw_->BindTexture(0, nullptr); + draw_->BindFramebufferAsRenderTarget(depalFBO, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }, "Depal"); - Draw::Framebuffer *depalFBO = framebufferManagerD3D11_->GetTempFBO(TempFBO::DEPAL, framebuffer->renderWidth, framebuffer->renderHeight); - shaderManager_->DirtyLastShader(); + draw_->SetScissorRect(0, 0, (int)framebuffer->renderWidth, (int)framebuffer->renderHeight); + Draw::Viewport vp{ 0.0f, 0.0f, (float)framebuffer->renderWidth, (float)framebuffer->renderHeight, 0.0f, 1.0f }; + draw_->SetViewports(1, &vp); - // Not sure why or if we need this here - we're not about to actually draw using draw_, just use its framebuffer binds. - draw_->InvalidateCachedState(); + TextureShaderApplier shaderApply(draw_, depalShader, framebuffer->bufferWidth, framebuffer->bufferHeight, framebuffer->renderWidth, framebuffer->renderHeight); + shaderApply.ApplyBounds(gstate_c.vertBounds, gstate_c.curTextureXOffset, gstate_c.curTextureYOffset); + shaderApply.Use(); - float xoff = -0.5f / framebuffer->renderWidth; - float yoff = 0.5f / framebuffer->renderHeight; - - TextureShaderApplierD3D11 shaderApply(context_, pshader, framebufferManagerD3D11_->GetDynamicQuadBuffer(), framebuffer->bufferWidth, framebuffer->bufferHeight, framebuffer->renderWidth, framebuffer->renderHeight, xoff, yoff); - shaderApply.ApplyBounds(gstate_c.vertBounds, gstate_c.curTextureXOffset, gstate_c.curTextureYOffset, xoff, yoff); - shaderApply.Use(depalShaderCache_->GetDepalettizeVertexShader(), depalShaderCache_->GetInputLayout()); - - ID3D11ShaderResourceView *nullTexture = nullptr; - context_->PSSetShaderResources(0, 1, &nullTexture); // In case the target was used in the last draw call. Happens in Sega Rally. - draw_->BindFramebufferAsRenderTarget(depalFBO, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }, "ApplyTextureFramebuffer_DepalShader"); - // BindAsClutTexture(clutTexture); - context_->PSSetShaderResources(1, 1, &clutTexture); - context_->PSSetSamplers(1, 1, &stockD3D11.samplerPoint2DWrap); draw_->BindFramebufferAsTexture(framebuffer->fbo, 0, depth ? Draw::FB_DEPTH_BIT : Draw::FB_COLOR_BIT, 0); - context_->PSSetSamplers(0, 1, &stockD3D11.samplerPoint2DWrap); + Draw::SamplerState *nearest = depalShaderCache_->GetSampler(); + draw_->BindSamplerStates(0, 1, &nearest); + draw_->BindSamplerStates(1, 1, &nearest); + draw_->BindTexture(1, clutTexture); + shaderApply.Shade(); - context_->PSSetShaderResources(0, 1, &nullTexture); // Make D3D11 validation happy. Really of no consequence since we rebind anyway. - framebufferManager_->RebindFramebuffer("RebindFramebuffer - ApplyTextureFramebuffer"); + framebufferManager_->RebindFramebuffer("ApplyTextureFramebuffer"); + draw_->BindFramebufferAsTexture(depalFBO, 0, Draw::FB_COLOR_BIT, 0); const u32 bytesPerColor = clutFormat == GE_CMODE_32BIT_ABGR8888 ? sizeof(u32) : sizeof(u16); const u32 clutTotalColors = clutMaxBytes_ / bytesPerColor; - CheckAlphaResult alphaStatus = CheckAlpha(clutBuf_, GetClutDestFormatD3D11(clutFormat), clutTotalColors); + CheckAlphaResult alphaStatus = CheckCLUTAlpha((const uint8_t *)clutBufRaw_, clutFormat, clutTotalColors); gstate_c.SetTextureFullAlpha(alphaStatus == CHECKALPHA_FULL); + + draw_->InvalidateCachedState(); + shaderManager_->DirtyLastShader(); } else { - framebufferManager_->RebindFramebuffer("RebindFramebuffer - ApplyTextureFramebuffer"); + framebufferManager_->RebindFramebuffer("ApplyTextureFramebuffer"); framebufferManager_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_MAY_COPY_WITH_UV | BINDFBCOLOR_APPLY_TEX_OFFSET); + + gstate_c.SetUseShaderDepal(false); gstate_c.SetTextureFullAlpha(gstate.getTextureFormat() == GE_TFMT_5650); } SamplerCacheKey samplerKey = GetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight); - ID3D11SamplerState *state = samplerCache_.GetOrCreateSampler(device_, samplerKey); - context_->PSSetSamplers(0, 1, &state); + ApplySamplingParams(samplerKey); gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_RASTER_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_BLEND_STATE | DIRTY_FRAGMENTSHADER_STATE | DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS); draw_->InvalidateCachedState(); diff --git a/GPU/D3D11/TextureCacheD3D11.h b/GPU/D3D11/TextureCacheD3D11.h index 74f71af794..b12f47953f 100644 --- a/GPU/D3D11/TextureCacheD3D11.h +++ b/GPU/D3D11/TextureCacheD3D11.h @@ -28,7 +28,7 @@ struct VirtualFramebuffer; class FramebufferManagerD3D11; -class DepalShaderCacheD3D11; +class DepalShaderCache; class ShaderManagerD3D11; class SamplerCacheD3D11 { @@ -49,7 +49,7 @@ public: void StartFrame(); void SetFramebufferManager(FramebufferManagerD3D11 *fbManager); - void SetDepalShaderCache(DepalShaderCacheD3D11 *dpCache) { + void SetDepalShaderCache(DepalShaderCache *dpCache) { depalShaderCache_ = dpCache; } void SetShaderManager(ShaderManagerD3D11 *sm) { @@ -66,6 +66,7 @@ protected: void Unbind() override; void ReleaseTexture(TexCacheEntry *entry, bool delete_them) override; void BindAsClutTexture(Draw::Texture *tex) override; + void ApplySamplingParams(const SamplerCacheKey &key) override; private: DXGI_FORMAT GetDestFormat(GETextureFormat format, GEPaletteFormat clutFormat) const; @@ -91,7 +92,7 @@ private: ID3D11Buffer *depalConstants_; FramebufferManagerD3D11 *framebufferManagerD3D11_; - DepalShaderCacheD3D11 *depalShaderCache_; + DepalShaderCache *depalShaderCache_; ShaderManagerD3D11 *shaderManager_; }; diff --git a/GPU/GLES/TextureCacheGLES.h b/GPU/GLES/TextureCacheGLES.h index ecaf761bb9..84d9f84850 100644 --- a/GPU/GLES/TextureCacheGLES.h +++ b/GPU/GLES/TextureCacheGLES.h @@ -71,7 +71,7 @@ protected: void BindAsClutTexture(Draw::Texture *tex) override; private: - void ApplySamplingParams(const SamplerCacheKey &key); + void ApplySamplingParams(const SamplerCacheKey &key) override; Draw::DataFormat GetDestFormat(GETextureFormat format, GEPaletteFormat clutFormat) const; void UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBase, bool clutIndexIsSimple) override; diff --git a/GPU/GPU.vcxproj b/GPU/GPU.vcxproj index 96f0fb05a9..6d75fffd7f 100644 --- a/GPU/GPU.vcxproj +++ b/GPU/GPU.vcxproj @@ -362,7 +362,6 @@ - @@ -505,7 +504,6 @@ - diff --git a/GPU/GPU.vcxproj.filters b/GPU/GPU.vcxproj.filters index 2f8533378f..349c938d96 100644 --- a/GPU/GPU.vcxproj.filters +++ b/GPU/GPU.vcxproj.filters @@ -195,9 +195,6 @@ D3D11 - - D3D11 - D3D11 @@ -443,9 +440,6 @@ D3D11 - - D3D11 - D3D11 diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index 3720c873e0..adf041556d 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -400,6 +400,10 @@ void TextureCacheVulkan::BindTexture(TexCacheEntry *entry) { gstate_c.SetUseShaderDepal(false); } +void TextureCacheVulkan::ApplySamplingParams(const SamplerCacheKey &key) { + curSampler_ = samplerCache_.GetOrCreateSampler(key); +} + void TextureCacheVulkan::Unbind() { imageView_ = VK_NULL_HANDLE; curSampler_ = VK_NULL_HANDLE; diff --git a/GPU/Vulkan/TextureCacheVulkan.h b/GPU/Vulkan/TextureCacheVulkan.h index c29a7756f7..0b4377aefb 100644 --- a/GPU/Vulkan/TextureCacheVulkan.h +++ b/GPU/Vulkan/TextureCacheVulkan.h @@ -103,6 +103,7 @@ protected: void Unbind() override; void ReleaseTexture(TexCacheEntry *entry, bool delete_them) override; void BindAsClutTexture(Draw::Texture *tex) override; + void ApplySamplingParams(const SamplerCacheKey &key) override; private: void LoadTextureLevel(TexCacheEntry &entry, uint8_t *writePtr, int rowPitch, int level, int scaleFactor, VkFormat dstFmt); diff --git a/UWP/GPU_UWP/GPU_UWP.vcxproj b/UWP/GPU_UWP/GPU_UWP.vcxproj index acda27f60f..f4aa428ba1 100644 --- a/UWP/GPU_UWP/GPU_UWP.vcxproj +++ b/UWP/GPU_UWP/GPU_UWP.vcxproj @@ -404,7 +404,6 @@ - @@ -466,7 +465,6 @@ - diff --git a/UWP/GPU_UWP/GPU_UWP.vcxproj.filters b/UWP/GPU_UWP/GPU_UWP.vcxproj.filters index 9dd217c598..c52ad15b96 100644 --- a/UWP/GPU_UWP/GPU_UWP.vcxproj.filters +++ b/UWP/GPU_UWP/GPU_UWP.vcxproj.filters @@ -24,7 +24,6 @@ - @@ -81,7 +80,6 @@ - diff --git a/libretro/Makefile.common b/libretro/Makefile.common index 316d8a7416..5cdd3008de 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -751,7 +751,6 @@ SOURCES_CXX += \ $(GPUDIR)/Directx9/TextureCacheDX9.cpp SOURCES_CXX += \ - $(GPUDIR)/D3D11/DepalettizeShaderD3D11.cpp \ $(GPUDIR)/D3D11/DrawEngineD3D11.cpp \ $(GPUDIR)/D3D11/FramebufferManagerD3D11.cpp \ $(GPUDIR)/D3D11/GPU_D3D11.cpp \