diff --git a/pcsx2/GS/GSState.cpp b/pcsx2/GS/GSState.cpp index 061b1203bb..06fabda36c 100644 --- a/pcsx2/GS/GSState.cpp +++ b/pcsx2/GS/GSState.cpp @@ -39,7 +39,7 @@ GSState::GSState() // m_nativeres seems to be a hack. Unfortunately it impacts draw call number which make debug painful in the replayer. // Let's keep it disabled to ease debug. m_nativeres = theApp.GetConfigI("upscale_multiplier") == 1; - m_mipmap = theApp.GetConfigI("mipmap"); + m_mipmap = theApp.GetConfigB("mipmap"); m_NTSC_Saturation = theApp.GetConfigB("NTSC_Saturation"); if (theApp.GetConfigB("UserHacks")) { diff --git a/pcsx2/GS/GSState.h b/pcsx2/GS/GSState.h index 3fe46f60f8..f21fe37d8f 100644 --- a/pcsx2/GS/GSState.h +++ b/pcsx2/GS/GSState.h @@ -219,7 +219,7 @@ public: int m_frameskip; bool m_NTSC_Saturation; bool m_nativeres; - int m_mipmap; + bool m_mipmap; static int s_n; bool s_dump; diff --git a/pcsx2/GS/Renderers/Common/GSDevice.cpp b/pcsx2/GS/Renderers/Common/GSDevice.cpp index 7c128cbb14..84629b2256 100644 --- a/pcsx2/GS/Renderers/Common/GSDevice.cpp +++ b/pcsx2/GS/Renderers/Common/GSDevice.cpp @@ -104,7 +104,7 @@ void GSDevice::RestoreAPIState() { } -GSTexture* GSDevice::FetchSurface(GSTexture::Type type, int w, int h, GSTexture::Format format, bool clear, bool prefer_reuse) +GSTexture* GSDevice::FetchSurface(GSTexture::Type type, int w, int h, bool mipmap, GSTexture::Format format, bool clear, bool prefer_reuse) { const GSVector2i size(w, h); const bool prefer_new_texture = (m_features.prefer_new_textures && type == GSTexture::Type::Texture && !prefer_reuse); @@ -118,7 +118,7 @@ GSTexture* GSDevice::FetchSurface(GSTexture::Type type, int w, int h, GSTexture: assert(t); - if (t->GetType() == type && t->GetFormat() == format && t->GetSize() == size) + if (t->GetType() == type && t->GetFormat() == format && t->GetSize() == size && t->IsMipmap() == mipmap) { if (!prefer_new_texture) { @@ -143,7 +143,7 @@ GSTexture* GSDevice::FetchSurface(GSTexture::Type type, int w, int h, GSTexture: } else { - t = CreateSurface(type, w, h, format); + t = CreateSurface(type, w, h, mipmap, format); if (!t) throw std::bad_alloc(); } @@ -243,32 +243,32 @@ void GSDevice::PurgePool() GSTexture* GSDevice::CreateSparseRenderTarget(int w, int h, GSTexture::Format format, bool clear) { - return FetchSurface(HasColorSparse() ? GSTexture::Type::SparseRenderTarget : GSTexture::Type::RenderTarget, w, h, format, clear, true); + return FetchSurface(HasColorSparse() ? GSTexture::Type::SparseRenderTarget : GSTexture::Type::RenderTarget, w, h, false, format, clear, true); } GSTexture* GSDevice::CreateSparseDepthStencil(int w, int h, GSTexture::Format format, bool clear) { - return FetchSurface(HasDepthSparse() ? GSTexture::Type::SparseDepthStencil : GSTexture::Type::DepthStencil, w, h, format, clear, true); + return FetchSurface(HasDepthSparse() ? GSTexture::Type::SparseDepthStencil : GSTexture::Type::DepthStencil, w, h, false, format, clear, true); } GSTexture* GSDevice::CreateRenderTarget(int w, int h, GSTexture::Format format, bool clear) { - return FetchSurface(GSTexture::Type::RenderTarget, w, h, format, clear, true); + return FetchSurface(GSTexture::Type::RenderTarget, w, h, false, format, clear, true); } GSTexture* GSDevice::CreateDepthStencil(int w, int h, GSTexture::Format format, bool clear) { - return FetchSurface(GSTexture::Type::DepthStencil, w, h, format, clear, true); + return FetchSurface(GSTexture::Type::DepthStencil, w, h, false, format, clear, true); } -GSTexture* GSDevice::CreateTexture(int w, int h, GSTexture::Format format, bool prefer_reuse) +GSTexture* GSDevice::CreateTexture(int w, int h, bool mipmap, GSTexture::Format format, bool prefer_reuse /* = false */) { - return FetchSurface(GSTexture::Type::Texture, w, h, format, false, prefer_reuse); + return FetchSurface(GSTexture::Type::Texture, w, h, mipmap, format, false, prefer_reuse); } GSTexture* GSDevice::CreateOffscreen(int w, int h, GSTexture::Format format) { - return FetchSurface(GSTexture::Type::Offscreen, w, h, format, false, true); + return FetchSurface(GSTexture::Type::Offscreen, w, h, false, format, false, true); } GSTexture::Format GSDevice::GetDefaultTextureFormat(GSTexture::Type type) @@ -428,10 +428,11 @@ bool GSDevice::ResizeTexture(GSTexture** t, GSTexture::Type type, int w, int h, if (t2 == NULL || t2->GetWidth() != w || t2->GetHeight() != h) { - GSTexture::Format fmt = t2 ? t2->GetFormat() : GetDefaultTextureFormat(type); + const GSTexture::Format fmt = t2 ? t2->GetFormat() : GetDefaultTextureFormat(type); + const bool mipmap = t2 ? t2->IsMipmap() : false; delete t2; - t2 = FetchSurface(type, w, h, fmt, clear, prefer_reuse); + t2 = FetchSurface(type, w, h, mipmap, fmt, clear, prefer_reuse); *t = t2; } diff --git a/pcsx2/GS/Renderers/Common/GSDevice.h b/pcsx2/GS/Renderers/Common/GSDevice.h index a18e081a47..d788e097e5 100644 --- a/pcsx2/GS/Renderers/Common/GSDevice.h +++ b/pcsx2/GS/Renderers/Common/GSDevice.h @@ -553,8 +553,8 @@ protected: bool m_rbswapped; FeatureSupport m_features; - virtual GSTexture* CreateSurface(GSTexture::Type type, int w, int h, GSTexture::Format format) = 0; - virtual GSTexture* FetchSurface(GSTexture::Type type, int w, int h, GSTexture::Format format, bool clear, bool prefer_reuse); + virtual GSTexture* CreateSurface(GSTexture::Type type, int w, int h, bool mipmap, GSTexture::Format format) = 0; + GSTexture* FetchSurface(GSTexture::Type type, int w, int h, bool mipmap, GSTexture::Format format, bool clear, bool prefer_reuse); virtual void DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex, GSVector4* dRect, const GSRegPMODE& PMODE, const GSRegEXTBUF& EXTBUF, const GSVector4& c) = 0; virtual void DoInterlace(GSTexture* sTex, GSTexture* dTex, int shader, bool linear, float yoffset) = 0; @@ -614,7 +614,7 @@ public: GSTexture* CreateSparseDepthStencil(int w, int h, GSTexture::Format format, bool clear = true); GSTexture* CreateRenderTarget(int w, int h, GSTexture::Format format, bool clear = true); GSTexture* CreateDepthStencil(int w, int h, GSTexture::Format format, bool clear = true); - GSTexture* CreateTexture(int w, int h, GSTexture::Format format, bool prefer_reuse = false); + GSTexture* CreateTexture(int w, int h, bool mipmap, GSTexture::Format format, bool prefer_reuse = false); GSTexture* CreateOffscreen(int w, int h, GSTexture::Format format); GSTexture::Format GetDefaultTextureFormat(GSTexture::Type type); diff --git a/pcsx2/GS/Renderers/Common/GSRenderer.cpp b/pcsx2/GS/Renderers/Common/GSRenderer.cpp index c651814e48..56ec9b7474 100644 --- a/pcsx2/GS/Renderers/Common/GSRenderer.cpp +++ b/pcsx2/GS/Renderers/Common/GSRenderer.cpp @@ -25,8 +25,6 @@ #include #endif -const unsigned int s_mipmap_nb = 3; - GSRenderer::GSRenderer() : m_shift_key(false) , m_control_key(false) @@ -580,11 +578,6 @@ void GSRenderer::KeyEvent(const HostKeyEvent& e) theApp.SetConfig("aa1", GSConfig.AA1); printf("GS: (Software) Edge anti-aliasing is now %s.\n", GSConfig.AA1 ? "enabled" : "disabled"); return; - case VK_INSERT: - m_mipmap = (m_mipmap + s_mipmap_nb + step) % s_mipmap_nb; - theApp.SetConfig("mipmap_hw", m_mipmap); - printf("GS: Mipmapping is now %s.\n", theApp.m_gs_hack.at(m_mipmap).name.c_str()); - return; case VK_NEXT: // As requested by Prafull, to be removed later char dither_msg[3][16] = {"disabled", "auto", "auto unscaled"}; GSConfig.Dithering = (GSConfig.Dithering + 1) % 3; diff --git a/pcsx2/GS/Renderers/Common/GSTexture.h b/pcsx2/GS/Renderers/Common/GSTexture.h index 1202d2f74a..3f5c02b2f5 100644 --- a/pcsx2/GS/Renderers/Common/GSTexture.h +++ b/pcsx2/GS/Renderers/Common/GSTexture.h @@ -95,6 +95,7 @@ public: int GetHeight() const { return m_size.y; } GSVector2i GetSize() const { return m_size; } int GetMipmapLevels() const { return m_mipmap_levels; } + bool IsMipmap() const { return m_mipmap_levels > 1; } Type GetType() const { return m_type; } Format GetFormat() const { return m_format; } diff --git a/pcsx2/GS/Renderers/DX11/GSDevice11.cpp b/pcsx2/GS/Renderers/DX11/GSDevice11.cpp index a46157f37f..53c093bcbc 100644 --- a/pcsx2/GS/Renderers/DX11/GSDevice11.cpp +++ b/pcsx2/GS/Renderers/DX11/GSDevice11.cpp @@ -34,7 +34,6 @@ GSDevice11::GSDevice11() m_state.topology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED; m_state.bf = -1; - m_mipmap = theApp.GetConfigI("mipmap"); m_upscale_multiplier = std::max(0, theApp.GetConfigI("upscale_multiplier")); m_features.geometry_shader = true; @@ -482,7 +481,7 @@ void GSDevice11::ClearStencil(GSTexture* t, u8 c) m_ctx->ClearDepthStencilView(*(GSTexture11*)t, D3D11_CLEAR_STENCIL, 0, c); } -GSTexture* GSDevice11::CreateSurface(GSTexture::Type type, int w, int h, GSTexture::Format format) +GSTexture* GSDevice11::CreateSurface(GSTexture::Type type, int w, int h, bool mipmap, GSTexture::Format format) { D3D11_TEXTURE2D_DESC desc; @@ -507,16 +506,12 @@ GSTexture* GSDevice11::CreateSurface(GSTexture::Type type, int w, int h, GSTextu desc.Width = std::max(1, std::min(w, m_d3d_texsize)); desc.Height = std::max(1, std::min(h, m_d3d_texsize)); desc.Format = dxformat; - desc.MipLevels = 1; + desc.MipLevels = mipmap ? (int)log2(std::max(w, h)) : 1; desc.ArraySize = 1; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.Usage = D3D11_USAGE_DEFAULT; - // mipmap = m_mipmap > 1 || m_filter != TriFiltering::None; - const bool mipmap = m_mipmap > 1; - const int layers = mipmap && format == GSTexture::Format::Color ? (int)log2(std::max(w, h)) : 1; - switch (type) { case GSTexture::Type::RenderTarget: @@ -527,7 +522,6 @@ GSTexture* GSDevice11::CreateSurface(GSTexture::Type type, int w, int h, GSTextu break; case GSTexture::Type::Texture: desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - desc.MipLevels = layers; break; case GSTexture::Type::Offscreen: desc.Usage = D3D11_USAGE_STAGING; diff --git a/pcsx2/GS/Renderers/DX11/GSDevice11.h b/pcsx2/GS/Renderers/DX11/GSDevice11.h index a1837b741b..185c3e5e7e 100644 --- a/pcsx2/GS/Renderers/DX11/GSDevice11.h +++ b/pcsx2/GS/Renderers/DX11/GSDevice11.h @@ -109,10 +109,9 @@ public: private: float m_hack_topleft_offset; int m_upscale_multiplier; - int m_mipmap; int m_d3d_texsize; - GSTexture* CreateSurface(GSTexture::Type type, int w, int h, GSTexture::Format format) final; + GSTexture* CreateSurface(GSTexture::Type type, int w, int h, bool mipmap, GSTexture::Format format) final; void DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex, GSVector4* dRect, const GSRegPMODE& PMODE, const GSRegEXTBUF& EXTBUF, const GSVector4& c) final; void DoInterlace(GSTexture* sTex, GSTexture* dTex, int shader, bool linear, float yoffset = 0) final; diff --git a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp index f6608ea8a9..4512adf775 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp +++ b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp @@ -26,6 +26,7 @@ GSRendererHW::GSRendererHW() , m_userhacks_ts_half_bottom(-1) , m_tc(new GSTextureCache(this)) , m_src(nullptr) + , m_hw_mipmap(GSConfig.HWMipmap) , m_userhacks_tcoffset(false) , m_userhacks_tcoffset_x(0) , m_userhacks_tcoffset_y(0) @@ -33,7 +34,7 @@ GSRendererHW::GSRendererHW() , m_reset(false) , m_lod(GSVector2i(0, 0)) { - m_mipmap = theApp.GetConfigI("mipmap_hw"); + m_mipmap = (m_hw_mipmap >= HWMipmapLevel::Basic); m_upscale_multiplier = std::max(0, theApp.GetConfigI("upscale_multiplier")); m_conservative_framebuffer = theApp.GetConfigB("conservative_framebuffer"); @@ -198,7 +199,8 @@ void GSRendererHW::SetGameCRC(u32 crc, int options) m_hacks.SetGameCRC(m_game); // Code for Automatic Mipmapping. Relies on game CRCs. - if (theApp.GetConfigT("mipmap_hw") == HWMipmapLevel::Automatic) + m_mipmap = (GSConfig.HWMipmap >= HWMipmapLevel::Basic); + if (GSConfig.HWMipmap == HWMipmapLevel::Automatic) { switch (CRC::Lookup(crc).title) { @@ -242,10 +244,12 @@ void GSRendererHW::SetGameCRC(u32 crc, int options) case CRC::TombRaiderAnniversary: case CRC::TribesAerialAssault: case CRC::Whiplash: - m_mipmap = static_cast(HWMipmapLevel::Basic); + m_hw_mipmap = HWMipmapLevel::Basic; + m_mipmap = true; break; default: - m_mipmap = static_cast(HWMipmapLevel::Off); + m_hw_mipmap = HWMipmapLevel::Off; + m_mipmap = false; break; } } @@ -1398,10 +1402,12 @@ void GSRendererHW::Draw() GetTextureMinMax(r, TEX0, MIP_CLAMP, m_vt.IsLinear()); - m_src = tex_psm.depth ? m_tc->LookupDepthSource(TEX0, env.TEXA, r) : m_tc->LookupSource(TEX0, env.TEXA, r); + m_src = tex_psm.depth ? m_tc->LookupDepthSource(TEX0, env.TEXA, r) : + m_tc->LookupSource(TEX0, env.TEXA, r, m_hw_mipmap >= HWMipmapLevel::Basic || + GSConfig.UserHacks_TriFilter == TriFiltering::Forced); // Round 2 - if (IsMipMapActive() && m_mipmap == 2 && !tex_psm.depth) + if (IsMipMapActive() && m_hw_mipmap == HWMipmapLevel::Full && !tex_psm.depth) { // Upload remaining texture layers const GSVector4 tmin = m_vt.m_min.t; @@ -2078,7 +2084,7 @@ bool GSRendererHW::OI_FFXII(GSTexture* rt, GSTexture* ds, GSTextureCache::Source g_gs_device->Recycle(t->m_texture); - t->m_texture = g_gs_device->CreateTexture(512, 512, GSTexture::Format::Color); + t->m_texture = g_gs_device->CreateTexture(512, 512, false, GSTexture::Format::Color); t->m_texture->Update(GSVector4i(0, 0, 448, lines), video, 448 * 4); diff --git a/pcsx2/GS/Renderers/HW/GSRendererHW.h b/pcsx2/GS/Renderers/HW/GSRendererHW.h index 67de7802dd..d442301a93 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererHW.h +++ b/pcsx2/GS/Renderers/HW/GSRendererHW.h @@ -146,6 +146,7 @@ protected: GSTextureCache* m_tc; GSVector4i m_r; GSTextureCache::Source* m_src; + HWMipmapLevel m_hw_mipmap; virtual void DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex) = 0; diff --git a/pcsx2/GS/Renderers/HW/GSRendererNew.cpp b/pcsx2/GS/Renderers/HW/GSRendererNew.cpp index 0e0180f8b5..477d13fdda 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererNew.cpp +++ b/pcsx2/GS/Renderers/HW/GSRendererNew.cpp @@ -773,7 +773,7 @@ void GSRendererNew::EmulateTextureSampler(const GSTextureCache::Source* tex) const bool need_mipmap = IsMipMapDraw(); const bool shader_emulated_sampler = tex->m_palette || cpsm.fmt != 0 || complex_wms_wmt || psm.depth; - const bool trilinear_manual = need_mipmap && m_mipmap == 2; + const bool trilinear_manual = need_mipmap && m_hw_mipmap == HWMipmapLevel::Full; bool bilinear = m_vt.IsLinear(); int trilinear = 0; @@ -782,11 +782,11 @@ void GSRendererNew::EmulateTextureSampler(const GSTextureCache::Source* tex) { case TriFiltering::Forced: trilinear = static_cast(GS_MIN_FILTER::Linear_Mipmap_Linear); - trilinear_auto = !need_mipmap || m_mipmap != 2; + trilinear_auto = !need_mipmap || m_hw_mipmap != HWMipmapLevel::Full; break; case TriFiltering::PS2: - if (need_mipmap && m_mipmap != 2) + if (need_mipmap && m_hw_mipmap != HWMipmapLevel::Full) { trilinear = m_context->TEX1.MMIN; trilinear_auto = true; diff --git a/pcsx2/GS/Renderers/HW/GSTextureCache.cpp b/pcsx2/GS/Renderers/HW/GSTextureCache.cpp index 4ca5869dea..13a5185ef9 100644 --- a/pcsx2/GS/Renderers/HW/GSTextureCache.cpp +++ b/pcsx2/GS/Renderers/HW/GSTextureCache.cpp @@ -109,7 +109,7 @@ GSTextureCache::Source* GSTextureCache::LookupDepthSource(const GIFRegTEX0& TEX0 { // JackieChan and SVCChaos cause regressions when skipping the draw calls when depth is disabled/not supported. // This way we make sure there are no regressions on D3D as well. - return LookupSource(TEX0, TEXA, r); + return LookupSource(TEX0, TEXA, r, false); } else { @@ -202,7 +202,7 @@ GSTextureCache::Source* GSTextureCache::LookupDepthSource(const GIFRegTEX0& TEX0 if (m_renderer->m_game.title == CRC::JackieChanAdv || m_renderer->m_game.title == CRC::SVCChaos) { // JackieChan and SVCChaos cause regressions when skipping the draw calls so we reuse the old code for these two. - return LookupSource(TEX0, TEXA, r); + return LookupSource(TEX0, TEXA, r, false); } else { @@ -219,7 +219,7 @@ GSTextureCache::Source* GSTextureCache::LookupDepthSource(const GIFRegTEX0& TEX0 return src; } -GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GSVector4i& r) +GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GSVector4i& r, bool mipmap) { const GSLocalMemory::psm_t& psm_s = GSLocalMemory::m_psm[TEX0.PSM]; //const GSLocalMemory::psm_t& cpsm = psm.pal > 0 ? GSLocalMemory::m_psm[TEX0.CPSM] : psm; @@ -475,7 +475,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, con GL_CACHE("TC: src miss (0x%x, 0x%x, %s)", TEX0.TBP0, psm_s.pal > 0 ? TEX0.CBP : 0, psm_str(TEX0.PSM)); } #endif - src = CreateSource(TEX0, TEXA, dst, half_right, x_offset, y_offset); + src = CreateSource(TEX0, TEXA, dst, half_right, x_offset, y_offset, mipmap); new_source = true; } else @@ -1282,7 +1282,7 @@ void GSTextureCache::IncAge() } //Fixme: Several issues in here. Not handling depth stencil, pitch conversion doesnt work. -GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, Target* dst, bool half_right, int x_offset, int y_offset) +GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, Target* dst, bool half_right, int x_offset, int y_offset, bool mipmap) { const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[TEX0.PSM]; Source* src = new Source(m_renderer, TEX0, TEXA, m_temp); @@ -1302,7 +1302,7 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con int h = (int)(scale.y * th); GSTexture* sTex = dst->m_texture; - GSTexture* dTex = g_gs_device->CreateTexture(w, h, GSTexture::Format::Color, true); + GSTexture* dTex = g_gs_device->CreateTexture(w, h, false, GSTexture::Format::Color, true); GSVector4i area(x, y, x + w, y + h); g_gs_device->CopyRect(sTex, dTex, area); @@ -1334,7 +1334,7 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con // So it could be tricky to put in the middle of the DrawPrims // Texture is created to keep code compatibility - GSTexture* dTex = g_gs_device->CreateTexture(tw, th, GSTexture::Format::Color, true); + GSTexture* dTex = g_gs_device->CreateTexture(tw, th, false, GSTexture::Format::Color, true); // Keep a trace of origin of the texture src->m_texture = dTex; @@ -1508,7 +1508,7 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con // 'src' is the new texture cache entry (hence the output) GSTexture* sTex = dst->m_texture; GSTexture* dTex = use_texture ? - g_gs_device->CreateTexture(w, h, GSTexture::Format::Color, true) : + g_gs_device->CreateTexture(w, h, false, GSTexture::Format::Color, true) : g_gs_device->CreateRenderTarget(w, h, GSTexture::Format::Color, !texture_completely_overwritten); src->m_texture = dTex; @@ -1614,12 +1614,12 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con { if (m_paltex && psm.pal > 0) { - src->m_texture = g_gs_device->CreateTexture(tw, th, GSTexture::Format::UNorm8); + src->m_texture = g_gs_device->CreateTexture(tw, th, false, GSTexture::Format::UNorm8); AttachPaletteToSource(src, psm.pal, true); } else { - src->m_texture = g_gs_device->CreateTexture(tw, th, GSTexture::Format::Color); + src->m_texture = g_gs_device->CreateTexture(tw, th, mipmap, GSTexture::Format::Color); if (psm.pal > 0) { AttachPaletteToSource(src, psm.pal, false); @@ -2274,7 +2274,7 @@ void GSTextureCache::Target::Update() TEXA.TA0 = 0; TEXA.TA1 = 0x80; - GSTexture* t = g_gs_device->CreateTexture(w, h, GSTexture::Format::Color); + GSTexture* t = g_gs_device->CreateTexture(w, h, false, GSTexture::Format::Color); GSOffset off = m_renderer->m_mem.GetOffset(m_TEX0.TBP0, m_TEX0.TBW, m_TEX0.PSM); @@ -2434,7 +2434,7 @@ void GSTextureCache::Palette::InitializeTexture() // sampling such texture are always normalized by 255. // This is because indexes are stored as normalized values of an RGBA texture (e.g. index 15 will be read as (15/255), // and therefore will read texel 15/255 * texture size). - m_tex_palette = g_gs_device->CreateTexture(256, 1, GSTexture::Format::Color); + m_tex_palette = g_gs_device->CreateTexture(256, 1, false, GSTexture::Format::Color); m_tex_palette->Update(GSVector4i(0, 0, m_pal, 1), m_clut, m_pal * sizeof(m_clut[0])); } } diff --git a/pcsx2/GS/Renderers/HW/GSTextureCache.h b/pcsx2/GS/Renderers/HW/GSTextureCache.h index b5c3168ab3..142dc8c0ef 100644 --- a/pcsx2/GS/Renderers/HW/GSTextureCache.h +++ b/pcsx2/GS/Renderers/HW/GSTextureCache.h @@ -232,7 +232,7 @@ protected: u8 m_texture_inside_rt_cache_size = 255; std::vector m_texture_inside_rt_cache; - Source* CreateSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, Target* t = NULL, bool half_right = false, int x_offset = 0, int y_offset = 0); + Source* CreateSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, Target* t = NULL, bool half_right = false, int x_offset = 0, int y_offset = 0, bool mipmap = false); Target* CreateTarget(const GIFRegTEX0& TEX0, int w, int h, int type); // TODO: virtual void Write(Source* s, const GSVector4i& r) = 0; @@ -246,7 +246,7 @@ public: void RemoveAll(); void RemovePartial(); - Source* LookupSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GSVector4i& r); + Source* LookupSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GSVector4i& r, bool mipmap); Source* LookupDepthSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GSVector4i& r, bool palette = false); Target* LookupTarget(const GIFRegTEX0& TEX0, int w, int h, int type, bool used, u32 fbmask = 0); diff --git a/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp b/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp index 780c4d3732..4b48a36eb5 100644 --- a/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp +++ b/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp @@ -63,7 +63,6 @@ GSDeviceOGL::GSDeviceOGL() memset(&m_om_dss, 0, sizeof(m_om_dss)); memset(&m_profiler, 0, sizeof(m_profiler)); - m_mipmap = theApp.GetConfigI("mipmap"); m_upscale_multiplier = std::max(1, theApp.GetConfigI("upscale_multiplier")); // Reset the debug file @@ -199,12 +198,12 @@ void GSDeviceOGL::GenerateProfilerData() } } -GSTexture* GSDeviceOGL::CreateSurface(GSTexture::Type type, int w, int h, GSTexture::Format fmt) +GSTexture* GSDeviceOGL::CreateSurface(GSTexture::Type type, int w, int h, bool mipmap, GSTexture::Format fmt) { GL_PUSH("Create surface"); // A wrapper to call GSTextureOGL, with the different kind of parameters. - GSTextureOGL* t = new GSTextureOGL(type, w, h, fmt, m_fbo_read, m_mipmap > 1 || GSConfig.UserHacks_TriFilter != TriFiltering::Off); + GSTextureOGL* t = new GSTextureOGL(type, w, h, fmt, m_fbo_read, mipmap); return t; } @@ -950,7 +949,7 @@ void GSDeviceOGL::InitPrimDateTexture(GSTexture* rt, const GSVector4i& area) // Create a texture to avoid the useless clean@0 if (m_date.t == NULL) - m_date.t = CreateTexture(rtsize.x, rtsize.y, GSTexture::Format::Int32); + m_date.t = CreateTexture(rtsize.x, rtsize.y, false, GSTexture::Format::Int32); // Clean with the max signed value const int max_int = 0x7FFFFFFF; diff --git a/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.h b/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.h index dbcc03f83b..c2c119248e 100644 --- a/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.h +++ b/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.h @@ -214,7 +214,6 @@ private: // Increment this constant whenever shaders change, to invalidate user's program binary cache. static constexpr u32 SHADER_VERSION = 1; - int m_mipmap; int m_upscale_multiplier; static FILE* m_debug_gl_file; @@ -301,7 +300,7 @@ private: AlignedBuffer m_download_buffer; - GSTexture* CreateSurface(GSTexture::Type type, int w, int h, GSTexture::Format format) final; + GSTexture* CreateSurface(GSTexture::Type type, int w, int h, bool mipmap, GSTexture::Format format) final; void DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex, GSVector4* dRect, const GSRegPMODE& PMODE, const GSRegEXTBUF& EXTBUF, const GSVector4& c) final; void DoInterlace(GSTexture* sTex, GSTexture* dTex, int shader, bool linear, float yoffset = 0) final; diff --git a/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp b/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp index b85aa45e3d..9e7bdd5c2d 100644 --- a/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp +++ b/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp @@ -338,17 +338,14 @@ void GSDeviceVK::ClearStencil(GSTexture* t, u8 c) static_cast(t)->TransitionToLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); } -GSTexture* GSDeviceVK::CreateSurface(GSTexture::Type type, int w, int h, GSTexture::Format format) +GSTexture* GSDeviceVK::CreateSurface(GSTexture::Type type, int w, int h, bool mipmap, GSTexture::Format format) { pxAssert(type != GSTexture::Type::Offscreen && type != GSTexture::Type::SparseRenderTarget && type != GSTexture::Type::SparseDepthStencil); const u32 width = std::max(1, std::min(w, g_vulkan_context->GetMaxImageDimension2D())); const u32 height = std::max(1, std::min(h, g_vulkan_context->GetMaxImageDimension2D())); - - const bool mipmap = - type == GSTexture::Type::Texture && (m_mipmap > 1 || GSConfig.UserHacks_TriFilter == TriFiltering::Forced); - const u32 layers = mipmap && format == GSTexture::Format::Color ? static_cast(log2(std::max(w, h))) : 1u; + const u32 layers = mipmap ? static_cast(log2(std::max(w, h))) : 1u; return GSTextureVK::Create(type, width, height, layers, format).release(); } diff --git a/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.h b/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.h index e85b1be1c2..507419d4b8 100644 --- a/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.h +++ b/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.h @@ -158,7 +158,7 @@ private: std::string m_tfx_source; - GSTexture* CreateSurface(GSTexture::Type type, int w, int h, GSTexture::Format format) override; + GSTexture* CreateSurface(GSTexture::Type type, int w, int h, bool mipmap, GSTexture::Format format) override; void DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex, GSVector4* dRect, const GSRegPMODE& PMODE, const GSRegEXTBUF& EXTBUF, const GSVector4& c) final;