mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-24 14:49:42 -06:00
VideoBackends: Move SamplerState to common
This commit is contained in:
@ -12,7 +12,7 @@
|
||||
|
||||
#include "VideoBackends/D3D/D3DBase.h"
|
||||
#include "VideoBackends/D3D/D3DState.h"
|
||||
#include "VideoCommon/SamplerCommon.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
|
||||
namespace DX11
|
||||
{
|
||||
@ -265,90 +265,55 @@ void StateManager::SetTextureByMask(u32 textureSlotMask, ID3D11ShaderResourceVie
|
||||
|
||||
ID3D11SamplerState* StateCache::Get(SamplerState state)
|
||||
{
|
||||
auto it = m_sampler.find(state.packed);
|
||||
|
||||
auto it = m_sampler.find(state.hex);
|
||||
if (it != m_sampler.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
|
||||
const unsigned int d3dMipFilters[4] = {
|
||||
TexMode0::TEXF_NONE, TexMode0::TEXF_POINT, TexMode0::TEXF_LINEAR,
|
||||
TexMode0::TEXF_NONE, // reserved
|
||||
};
|
||||
const D3D11_TEXTURE_ADDRESS_MODE d3dClamps[4] = {
|
||||
D3D11_TEXTURE_ADDRESS_CLAMP, D3D11_TEXTURE_ADDRESS_WRAP, D3D11_TEXTURE_ADDRESS_MIRROR,
|
||||
D3D11_TEXTURE_ADDRESS_WRAP // reserved
|
||||
};
|
||||
|
||||
D3D11_SAMPLER_DESC sampdc = CD3D11_SAMPLER_DESC(CD3D11_DEFAULT());
|
||||
|
||||
unsigned int mip = d3dMipFilters[state.min_filter & 3];
|
||||
|
||||
if (state.max_anisotropy > 1 && !SamplerCommon::IsBpTexMode0PointFiltering(state))
|
||||
if (state.mipmap_filter == SamplerState::Filter::Linear)
|
||||
{
|
||||
sampdc.Filter = D3D11_FILTER_ANISOTROPIC;
|
||||
sampdc.MaxAnisotropy = (u32)state.max_anisotropy;
|
||||
if (state.min_filter == SamplerState::Filter::Linear)
|
||||
sampdc.Filter = (state.mag_filter == SamplerState::Filter::Linear) ?
|
||||
D3D11_FILTER_MIN_MAG_MIP_LINEAR :
|
||||
D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR;
|
||||
else
|
||||
sampdc.Filter = (state.mag_filter == SamplerState::Filter::Linear) ?
|
||||
D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR :
|
||||
D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR;
|
||||
}
|
||||
else if (state.min_filter & 4) // linear min filter
|
||||
else
|
||||
{
|
||||
if (state.mag_filter) // linear mag filter
|
||||
{
|
||||
if (mip == TexMode0::TEXF_NONE)
|
||||
sampdc.Filter = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT;
|
||||
else if (mip == TexMode0::TEXF_POINT)
|
||||
sampdc.Filter = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT;
|
||||
else if (mip == TexMode0::TEXF_LINEAR)
|
||||
sampdc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
|
||||
}
|
||||
else // point mag filter
|
||||
{
|
||||
if (mip == TexMode0::TEXF_NONE)
|
||||
sampdc.Filter = D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT;
|
||||
else if (mip == TexMode0::TEXF_POINT)
|
||||
sampdc.Filter = D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT;
|
||||
else if (mip == TexMode0::TEXF_LINEAR)
|
||||
sampdc.Filter = D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR;
|
||||
}
|
||||
}
|
||||
else // point min filter
|
||||
{
|
||||
if (state.mag_filter) // linear mag filter
|
||||
{
|
||||
if (mip == TexMode0::TEXF_NONE)
|
||||
sampdc.Filter = D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT;
|
||||
else if (mip == TexMode0::TEXF_POINT)
|
||||
sampdc.Filter = D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT;
|
||||
else if (mip == TexMode0::TEXF_LINEAR)
|
||||
sampdc.Filter = D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR;
|
||||
}
|
||||
else // point mag filter
|
||||
{
|
||||
if (mip == TexMode0::TEXF_NONE)
|
||||
sampdc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
|
||||
else if (mip == TexMode0::TEXF_POINT)
|
||||
sampdc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
|
||||
else if (mip == TexMode0::TEXF_LINEAR)
|
||||
sampdc.Filter = D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR;
|
||||
}
|
||||
if (state.min_filter == SamplerState::Filter::Linear)
|
||||
sampdc.Filter = (state.mag_filter == SamplerState::Filter::Linear) ?
|
||||
D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT :
|
||||
D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT;
|
||||
else
|
||||
sampdc.Filter = (state.mag_filter == SamplerState::Filter::Linear) ?
|
||||
D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT :
|
||||
D3D11_FILTER_MIN_MAG_MIP_POINT;
|
||||
}
|
||||
|
||||
sampdc.AddressU = d3dClamps[state.wrap_s];
|
||||
sampdc.AddressV = d3dClamps[state.wrap_t];
|
||||
|
||||
sampdc.MaxLOD = SamplerCommon::AreBpTexMode0MipmapsEnabled(state) ? state.max_lod / 16.f : 0.f;
|
||||
sampdc.MinLOD = std::min(state.min_lod / 16.f, sampdc.MaxLOD);
|
||||
static constexpr std::array<D3D11_TEXTURE_ADDRESS_MODE, 3> address_modes = {
|
||||
{D3D11_TEXTURE_ADDRESS_CLAMP, D3D11_TEXTURE_ADDRESS_WRAP, D3D11_TEXTURE_ADDRESS_MIRROR}};
|
||||
sampdc.AddressU = address_modes[static_cast<u32>(state.wrap_u.Value())];
|
||||
sampdc.AddressV = address_modes[static_cast<u32>(state.wrap_v.Value())];
|
||||
sampdc.MaxLOD = state.max_lod / 16.f;
|
||||
sampdc.MinLOD = state.min_lod / 16.f;
|
||||
sampdc.MipLODBias = (s32)state.lod_bias / 32.0f;
|
||||
|
||||
ID3D11SamplerState* res = nullptr;
|
||||
if (state.anisotropic_filtering)
|
||||
{
|
||||
sampdc.Filter = D3D11_FILTER_ANISOTROPIC;
|
||||
sampdc.MaxAnisotropy = 1u << g_ActiveConfig.iMaxAnisotropy;
|
||||
}
|
||||
|
||||
ID3D11SamplerState* res = nullptr;
|
||||
HRESULT hr = D3D::device->CreateSamplerState(&sampdc, &res);
|
||||
if (FAILED(hr))
|
||||
PanicAlert("Fail %s %d\n", __FILE__, __LINE__);
|
||||
|
||||
D3D::SetDebugObjectName(res, "sampler state used to emulate the GX pipeline");
|
||||
m_sampler.emplace(state.packed, res);
|
||||
|
||||
m_sampler.emplace(state.hex, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -20,20 +20,6 @@ struct ID3D11RasterizerState;
|
||||
|
||||
namespace DX11
|
||||
{
|
||||
union SamplerState
|
||||
{
|
||||
BitField<0, 3, u64> min_filter;
|
||||
BitField<3, 1, u64> mag_filter;
|
||||
BitField<4, 8, u64> min_lod;
|
||||
BitField<12, 8, u64> max_lod;
|
||||
BitField<20, 8, s64> lod_bias;
|
||||
BitField<28, 2, u64> wrap_s;
|
||||
BitField<30, 2, u64> wrap_t;
|
||||
BitField<32, 5, u64> max_anisotropy;
|
||||
|
||||
u64 packed;
|
||||
};
|
||||
|
||||
class StateCache
|
||||
{
|
||||
public:
|
||||
@ -54,7 +40,7 @@ private:
|
||||
std::unordered_map<u32, ID3D11DepthStencilState*> m_depth;
|
||||
std::unordered_map<u32, ID3D11RasterizerState*> m_raster;
|
||||
std::unordered_map<u32, ID3D11BlendState*> m_blend;
|
||||
std::unordered_map<u64, ID3D11SamplerState*> m_sampler;
|
||||
std::unordered_map<u32, ID3D11SamplerState*> m_sampler;
|
||||
};
|
||||
|
||||
namespace D3D
|
||||
|
@ -249,7 +249,7 @@ Renderer::Renderer() : ::Renderer(D3D::GetBackBufferWidth(), D3D::GetBackBufferH
|
||||
|
||||
// Setup GX pipeline state
|
||||
for (auto& sampler : s_gx_state.samplers)
|
||||
sampler.packed = 0;
|
||||
sampler.hex = RenderState::GetPointSamplerState().hex;
|
||||
|
||||
s_gx_state.zmode.testenable = false;
|
||||
s_gx_state.zmode.updateenable = false;
|
||||
@ -870,12 +870,8 @@ void Renderer::ApplyState()
|
||||
StateCache::GetPrimitiveTopology(s_gx_state.raster.primitive));
|
||||
FramebufferManager::SetIntegerEFBRenderTarget(s_gx_state.blend.logicopenable);
|
||||
|
||||
for (size_t stage = 0; stage < s_gx_state.samplers.size(); stage++)
|
||||
{
|
||||
// TODO: cache SamplerState directly, not d3d object
|
||||
s_gx_state.samplers[stage].max_anisotropy = UINT64_C(1) << g_ActiveConfig.iMaxAnisotropy;
|
||||
for (u32 stage = 0; stage < static_cast<u32>(s_gx_state.samplers.size()); stage++)
|
||||
D3D::stateman->SetSampler(stage, s_gx_state_cache.Get(s_gx_state.samplers[stage]));
|
||||
}
|
||||
|
||||
ID3D11Buffer* vertexConstants = VertexShaderCache::GetConstantBuffer();
|
||||
|
||||
@ -902,38 +898,9 @@ void Renderer::SetDepthState(const DepthState& state)
|
||||
s_gx_state.zmode.hex = state.hex;
|
||||
}
|
||||
|
||||
void Renderer::SetSamplerState(int stage, int texindex, bool custom_tex)
|
||||
void Renderer::SetSamplerState(u32 index, const SamplerState& state)
|
||||
{
|
||||
const FourTexUnits& tex = bpmem.tex[texindex];
|
||||
const TexMode0& tm0 = tex.texMode0[stage];
|
||||
const TexMode1& tm1 = tex.texMode1[stage];
|
||||
|
||||
if (texindex)
|
||||
stage += 4;
|
||||
|
||||
if (g_ActiveConfig.bForceFiltering)
|
||||
{
|
||||
// Only use mipmaps if the game says they are available.
|
||||
s_gx_state.samplers[stage].min_filter = SamplerCommon::AreBpTexMode0MipmapsEnabled(tm0) ? 6 : 4;
|
||||
s_gx_state.samplers[stage].mag_filter = 1; // linear mag
|
||||
}
|
||||
else
|
||||
{
|
||||
s_gx_state.samplers[stage].min_filter = (u32)tm0.min_filter;
|
||||
s_gx_state.samplers[stage].mag_filter = (u32)tm0.mag_filter;
|
||||
}
|
||||
|
||||
s_gx_state.samplers[stage].wrap_s = (u32)tm0.wrap_s;
|
||||
s_gx_state.samplers[stage].wrap_t = (u32)tm0.wrap_t;
|
||||
s_gx_state.samplers[stage].max_lod = (u32)tm1.max_lod;
|
||||
s_gx_state.samplers[stage].min_lod = (u32)tm1.min_lod;
|
||||
s_gx_state.samplers[stage].lod_bias = (s32)tm0.lod_bias;
|
||||
|
||||
// custom textures may have higher resolution, so disable the max_lod
|
||||
if (custom_tex)
|
||||
{
|
||||
s_gx_state.samplers[stage].max_lod = 255;
|
||||
}
|
||||
s_gx_state.samplers[index].hex = state.hex;
|
||||
}
|
||||
|
||||
void Renderer::SetInterlacingMode()
|
||||
|
@ -23,7 +23,7 @@ public:
|
||||
void SetScissorRect(const EFBRectangle& rc) override;
|
||||
void SetRasterizationState(const RasterizationState& state) override;
|
||||
void SetDepthState(const DepthState& state) override;
|
||||
void SetSamplerState(int stage, int texindex, bool custom_tex) override;
|
||||
void SetSamplerState(u32 index, const SamplerState& state) override;
|
||||
void SetInterlacingMode() override;
|
||||
void SetViewport() override;
|
||||
void SetFullscreen(bool enable_fullscreen) override;
|
||||
|
Reference in New Issue
Block a user