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.Height = std::max(1, std::min(h, m_d3d_texsize));
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.SampleDesc.Count = 1;
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;
break;
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;
case GSTexture::Type::Offscreen:
desc.Usage = D3D11_USAGE_STAGING;
@ -536,7 +537,7 @@ GSTexture* GSDevice11::CreateSurface(GSTexture::Type type, int w, int h, bool mi
if (SUCCEEDED(hr))
{
t = new GSTexture11(std::move(texture), format);
t = new GSTexture11(std::move(texture), type, format);
assert(type == t->GetType());
}
else
@ -1386,16 +1387,10 @@ static void preprocessSel(GSDevice11::PSSelector& sel)
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)
{
ASSERT(!config.require_full_barrier); // We always specify no support so it shouldn't request this
preprocessSel(config.ps);
preprocessSel(config.sampler);
if (config.destination_alpha != GSHWDrawConfig::DestinationAlphaMode::Off)
{

View File

@ -18,7 +18,7 @@
#include "GS/GSPng.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)
{
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.y = (int)m_desc.Height;
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_type = type;
m_format = format;
m_max_layer = m_desc.MipLevels;
m_mipmap_levels = static_cast<int>(m_desc.MipLevels);
}
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)
{
if (layer >= m_max_layer)
return true;
if (layer >= m_mipmap_levels)
return false;
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).
m_ctx->UpdateSubresource(m_texture.get(), subresource, &box, data, pitch, 0);
m_needs_mipmaps_generated |= (layer == 0);
return true;
}
@ -78,7 +69,7 @@ bool GSTexture11::Map(GSMap& m, const GSVector4i* r, int layer)
return false;
}
if (layer >= m_max_layer)
if (layer >= m_mipmap_levels)
return false;
if (m_texture && m_desc.Usage == D3D11_USAGE_STAGING)
@ -105,6 +96,7 @@ void GSTexture11::Unmap()
if (m_texture)
{
UINT subresource = m_layer;
m_needs_mipmaps_generated |= (m_layer == 0);
m_ctx->Unmap(m_texture.get(), subresource);
}
}
@ -208,6 +200,11 @@ bool GSTexture11::Save(const std::string& fn)
return success;
}
void GSTexture11::GenerateMipmap()
{
m_ctx->GenerateMips(operator ID3D11ShaderResourceView*());
}
GSTexture11::operator ID3D11Texture2D*()
{
return m_texture.get();

View File

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

View File

@ -354,7 +354,6 @@ HacksTab::HacksTab(wxWindow* parent)
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_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(); };
PaddedBoxSizer<wxStaticBoxSizer> rend_hacks_box (wxVERTICAL, this, "Renderer Hacks");
@ -384,7 +383,7 @@ HacksTab::HacksTab(wxWindow* parent)
// 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, "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
add_label(this, rend_hack_choice_grid, "Skipdraw Range:", IDC_SKIPDRAWHACK);