GS/DX11: Fix mipmap textures and support trilinear

This commit is contained in:
Connor McLaughlin 2022-01-09 15:23:29 +10:00 committed by lightningterror
parent 6182b46033
commit 1518b793dc
4 changed files with 25 additions and 34 deletions

View File

@ -506,7 +506,7 @@ GSTexture* GSDevice11::CreateSurface(GSTexture::Type type, int w, int h, bool mi
desc.Width = std::max(1, std::min(w, m_d3d_texsize)); desc.Width = std::max(1, std::min(w, m_d3d_texsize));
desc.Height = std::max(1, std::min(h, m_d3d_texsize)); desc.Height = std::max(1, std::min(h, m_d3d_texsize));
desc.Format = dxformat; desc.Format = dxformat;
desc.MipLevels = mipmap ? (int)log2(std::max(w, h)) : 1; desc.MipLevels = mipmap ? (int)log2(std::max(desc.Width, desc.Height)) : 1;
desc.ArraySize = 1; desc.ArraySize = 1;
desc.SampleDesc.Count = 1; desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0; desc.SampleDesc.Quality = 0;
@ -521,7 +521,8 @@ GSTexture* GSDevice11::CreateSurface(GSTexture::Type type, int w, int h, bool mi
desc.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE; desc.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE;
break; break;
case GSTexture::Type::Texture: case GSTexture::Type::Texture:
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; desc.BindFlags = mipmap ? (D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE) : D3D11_BIND_SHADER_RESOURCE;
desc.MiscFlags = mipmap ? D3D11_RESOURCE_MISC_GENERATE_MIPS : 0;
break; break;
case GSTexture::Type::Offscreen: case GSTexture::Type::Offscreen:
desc.Usage = D3D11_USAGE_STAGING; desc.Usage = D3D11_USAGE_STAGING;
@ -536,7 +537,7 @@ GSTexture* GSDevice11::CreateSurface(GSTexture::Type type, int w, int h, bool mi
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
t = new GSTexture11(std::move(texture), format); t = new GSTexture11(std::move(texture), type, format);
assert(type == t->GetType()); assert(type == t->GetType());
} }
else else
@ -1386,16 +1387,10 @@ static void preprocessSel(GSDevice11::PSSelector& sel)
sel.manual_lod = 0; // Not currently supported in DX11 sel.manual_lod = 0; // Not currently supported in DX11
} }
static void preprocessSel(GSDevice11::PSSamplerSelector& sel)
{
sel.triln = 0; // Not currently supported
}
void GSDevice11::RenderHW(GSHWDrawConfig& config) void GSDevice11::RenderHW(GSHWDrawConfig& config)
{ {
ASSERT(!config.require_full_barrier); // We always specify no support so it shouldn't request this ASSERT(!config.require_full_barrier); // We always specify no support so it shouldn't request this
preprocessSel(config.ps); preprocessSel(config.ps);
preprocessSel(config.sampler);
if (config.destination_alpha != GSHWDrawConfig::DestinationAlphaMode::Off) if (config.destination_alpha != GSHWDrawConfig::DestinationAlphaMode::Off)
{ {

View File

@ -18,7 +18,7 @@
#include "GS/GSPng.h" #include "GS/GSPng.h"
#include "GS/GSPerfMon.h" #include "GS/GSPerfMon.h"
GSTexture11::GSTexture11(wil::com_ptr_nothrow<ID3D11Texture2D> texture, GSTexture::Format format) GSTexture11::GSTexture11(wil::com_ptr_nothrow<ID3D11Texture2D> texture, GSTexture::Type type, GSTexture::Format format)
: m_texture(std::move(texture)), m_layer(0) : m_texture(std::move(texture)), m_layer(0)
{ {
ASSERT(m_texture); ASSERT(m_texture);
@ -30,19 +30,10 @@ GSTexture11::GSTexture11(wil::com_ptr_nothrow<ID3D11Texture2D> texture, GSTextur
m_size.x = (int)m_desc.Width; m_size.x = (int)m_desc.Width;
m_size.y = (int)m_desc.Height; m_size.y = (int)m_desc.Height;
m_type = type;
if (m_desc.BindFlags & D3D11_BIND_RENDER_TARGET)
m_type = Type::RenderTarget;
else if (m_desc.BindFlags & D3D11_BIND_DEPTH_STENCIL)
m_type = Type::DepthStencil;
else if (m_desc.BindFlags & D3D11_BIND_SHADER_RESOURCE)
m_type = Type::Texture;
else if (m_desc.Usage == D3D11_USAGE_STAGING)
m_type = Type::Offscreen;
m_format = format; m_format = format;
m_max_layer = m_desc.MipLevels; m_mipmap_levels = static_cast<int>(m_desc.MipLevels);
} }
void* GSTexture11::GetNativeHandle() const void* GSTexture11::GetNativeHandle() const
@ -52,8 +43,8 @@ void* GSTexture11::GetNativeHandle() const
bool GSTexture11::Update(const GSVector4i& r, const void* data, int pitch, int layer) bool GSTexture11::Update(const GSVector4i& r, const void* data, int pitch, int layer)
{ {
if (layer >= m_max_layer) if (layer >= m_mipmap_levels)
return true; return false;
if (m_dev && m_texture) if (m_dev && m_texture)
{ {
@ -63,7 +54,7 @@ bool GSTexture11::Update(const GSVector4i& r, const void* data, int pitch, int l
UINT subresource = layer; // MipSlice + (ArraySlice * MipLevels). UINT subresource = layer; // MipSlice + (ArraySlice * MipLevels).
m_ctx->UpdateSubresource(m_texture.get(), subresource, &box, data, pitch, 0); m_ctx->UpdateSubresource(m_texture.get(), subresource, &box, data, pitch, 0);
m_needs_mipmaps_generated |= (layer == 0);
return true; return true;
} }
@ -78,7 +69,7 @@ bool GSTexture11::Map(GSMap& m, const GSVector4i* r, int layer)
return false; return false;
} }
if (layer >= m_max_layer) if (layer >= m_mipmap_levels)
return false; return false;
if (m_texture && m_desc.Usage == D3D11_USAGE_STAGING) if (m_texture && m_desc.Usage == D3D11_USAGE_STAGING)
@ -105,6 +96,7 @@ void GSTexture11::Unmap()
if (m_texture) if (m_texture)
{ {
UINT subresource = m_layer; UINT subresource = m_layer;
m_needs_mipmaps_generated |= (m_layer == 0);
m_ctx->Unmap(m_texture.get(), subresource); m_ctx->Unmap(m_texture.get(), subresource);
} }
} }
@ -208,6 +200,11 @@ bool GSTexture11::Save(const std::string& fn)
return success; return success;
} }
void GSTexture11::GenerateMipmap()
{
m_ctx->GenerateMips(operator ID3D11ShaderResourceView*());
}
GSTexture11::operator ID3D11Texture2D*() GSTexture11::operator ID3D11Texture2D*()
{ {
return m_texture.get(); return m_texture.get();

View File

@ -20,7 +20,7 @@
#include <wil/com.h> #include <wil/com.h>
#include <d3d11.h> #include <d3d11.h>
class GSTexture11 : public GSTexture class GSTexture11 final : public GSTexture
{ {
wil::com_ptr_nothrow<ID3D11Device> m_dev; wil::com_ptr_nothrow<ID3D11Device> m_dev;
wil::com_ptr_nothrow<ID3D11DeviceContext> m_ctx; wil::com_ptr_nothrow<ID3D11DeviceContext> m_ctx;
@ -31,17 +31,17 @@ class GSTexture11 : public GSTexture
wil::com_ptr_nothrow<ID3D11DepthStencilView> m_dsv; wil::com_ptr_nothrow<ID3D11DepthStencilView> m_dsv;
int m_layer; int m_layer;
int m_max_layer;
public: public:
explicit GSTexture11(wil::com_ptr_nothrow<ID3D11Texture2D> texture, GSTexture::Format format); explicit GSTexture11(wil::com_ptr_nothrow<ID3D11Texture2D> texture, GSTexture::Type type, GSTexture::Format format);
void* GetNativeHandle() const override; void* GetNativeHandle() const override;
bool Update(const GSVector4i& r, const void* data, int pitch, int layer = 0); bool Update(const GSVector4i& r, const void* data, int pitch, int layer = 0) override;
bool Map(GSMap& m, const GSVector4i* r = NULL, int layer = 0); bool Map(GSMap& m, const GSVector4i* r = NULL, int layer = 0) override;
void Unmap(); void Unmap() override;
bool Save(const std::string& fn); bool Save(const std::string& fn) override;
void GenerateMipmap() override;
bool Equal(GSTexture11* tex); bool Equal(GSTexture11* tex);
operator ID3D11Texture2D*(); operator ID3D11Texture2D*();

View File

@ -354,7 +354,6 @@ HacksTab::HacksTab(wxWindow* parent)
auto hw_prereq = [this]{ return m_is_hardware; }; auto hw_prereq = [this]{ return m_is_hardware; };
auto* hacks_check_box = m_ui.addCheckBox(tab_box.inner, "Enable HW Hacks", "UserHacks", -1, hw_prereq); auto* hacks_check_box = m_ui.addCheckBox(tab_box.inner, "Enable HW Hacks", "UserHacks", -1, hw_prereq);
auto hacks_prereq = [this, hacks_check_box]{ return m_is_hardware && hacks_check_box->GetValue(); }; auto hacks_prereq = [this, hacks_check_box]{ return m_is_hardware && hacks_check_box->GetValue(); };
auto gl_or_vk_hacks_prereq = [this, hacks_check_box]{ return (m_is_ogl_hw || m_is_vk_hw) && hacks_check_box->GetValue(); };
auto upscale_hacks_prereq = [this, hacks_check_box]{ return !m_is_native_res && hacks_check_box->GetValue(); }; auto upscale_hacks_prereq = [this, hacks_check_box]{ return !m_is_native_res && hacks_check_box->GetValue(); };
PaddedBoxSizer<wxStaticBoxSizer> rend_hacks_box (wxVERTICAL, this, "Renderer Hacks"); PaddedBoxSizer<wxStaticBoxSizer> rend_hacks_box (wxVERTICAL, this, "Renderer Hacks");
@ -384,7 +383,7 @@ HacksTab::HacksTab(wxWindow* parent)
// Renderer Hacks: // Renderer Hacks:
m_ui.addComboBoxAndLabel(rend_hack_choice_grid, "Half Screen Fix:", "UserHacks_Half_Bottom_Override", &theApp.m_gs_generic_list, IDC_HALF_SCREEN_TS, hacks_prereq); m_ui.addComboBoxAndLabel(rend_hack_choice_grid, "Half Screen Fix:", "UserHacks_Half_Bottom_Override", &theApp.m_gs_generic_list, IDC_HALF_SCREEN_TS, hacks_prereq);
m_ui.addComboBoxAndLabel(rend_hack_choice_grid, "Trilinear Filtering:", "UserHacks_TriFilter", &theApp.m_gs_trifilter, IDC_TRI_FILTER, gl_or_vk_hacks_prereq); m_ui.addComboBoxAndLabel(rend_hack_choice_grid, "Trilinear Filtering:", "UserHacks_TriFilter", &theApp.m_gs_trifilter, IDC_TRI_FILTER, hacks_prereq);
// Skipdraw Range // Skipdraw Range
add_label(this, rend_hack_choice_grid, "Skipdraw Range:", IDC_SKIPDRAWHACK); add_label(this, rend_hack_choice_grid, "Skipdraw Range:", IDC_SKIPDRAWHACK);