1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-03-13 19:29:14 +01:00

[d3d9] Remove internal sampler pool

We have a sampler pool in the backend now, let's use it.
This commit is contained in:
Philip Rebohle 2024-09-27 16:41:54 +02:00 committed by Philip Rebohle
parent 707ddd63a1
commit c7dab6a442
6 changed files with 45 additions and 207 deletions

View File

@ -6638,36 +6638,56 @@ namespace dxvk {
void D3D9DeviceEx::BindSampler(DWORD Sampler) {
auto& state = m_state.samplerStates[Sampler];
D3D9SamplerKey key;
key.AddressU = D3DTEXTUREADDRESS(state[D3DSAMP_ADDRESSU]);
key.AddressV = D3DTEXTUREADDRESS(state[D3DSAMP_ADDRESSV]);
key.AddressW = D3DTEXTUREADDRESS(state[D3DSAMP_ADDRESSW]);
key.MagFilter = D3DTEXTUREFILTERTYPE(state[D3DSAMP_MAGFILTER]);
key.MinFilter = D3DTEXTUREFILTERTYPE(state[D3DSAMP_MINFILTER]);
key.MipFilter = D3DTEXTUREFILTERTYPE(state[D3DSAMP_MIPFILTER]);
key.MaxAnisotropy = state[D3DSAMP_MAXANISOTROPY];
key.MipmapLodBias = bit::cast<float>(state[D3DSAMP_MIPMAPLODBIAS]);
key.MaxMipLevel = state[D3DSAMP_MAXMIPLEVEL];
key.BorderColor = D3DCOLOR(state[D3DSAMP_BORDERCOLOR]);
key.Depth = m_depthTextures & (1u << Sampler);
D3DTEXTUREFILTERTYPE minFilter = D3DTEXTUREFILTERTYPE(state[D3DSAMP_MINFILTER]);
D3DTEXTUREFILTERTYPE magFilter = D3DTEXTUREFILTERTYPE(state[D3DSAMP_MAGFILTER]);
D3DTEXTUREFILTERTYPE mipFilter = D3DTEXTUREFILTERTYPE(state[D3DSAMP_MIPFILTER]);
DxvkSamplerKey key = { };
key.setFilter(
DecodeFilter(minFilter),
DecodeFilter(magFilter),
DecodeMipFilter(mipFilter).MipFilter);
if (m_cubeTextures & (1u << Sampler)) {
key.AddressU = D3DTADDRESS_CLAMP;
key.AddressV = D3DTADDRESS_CLAMP;
key.AddressW = D3DTADDRESS_CLAMP;
key.setAddressModes(
VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE);
key.setLegacyCubeFilter(!m_d3d9Options.seamlessCubes);
} else {
key.setAddressModes(
DecodeAddressMode(D3DTEXTUREADDRESS(state[D3DSAMP_ADDRESSU])),
DecodeAddressMode(D3DTEXTUREADDRESS(state[D3DSAMP_ADDRESSV])),
DecodeAddressMode(D3DTEXTUREADDRESS(state[D3DSAMP_ADDRESSW])));
}
if (m_d3d9Options.samplerAnisotropy != -1) {
if (key.MagFilter == D3DTEXF_LINEAR)
key.MagFilter = D3DTEXF_ANISOTROPIC;
key.setDepthCompare(m_depthTextures & (1u << Sampler), VK_COMPARE_OP_LESS_OR_EQUAL);
if (key.MinFilter == D3DTEXF_LINEAR)
key.MinFilter = D3DTEXF_ANISOTROPIC;
if (mipFilter != D3DTEXF_NONE) {
// Anisotropic filtering doesn't make any sense with only one mip
uint32_t anisotropy = state[D3DSAMP_MAXANISOTROPY];
key.MaxAnisotropy = m_d3d9Options.samplerAnisotropy;
if (minFilter != D3DTEXF_ANISOTROPIC)
anisotropy = 0u;
if (m_d3d9Options.samplerAnisotropy != -1 && minFilter > D3DTEXF_POINT)
anisotropy = m_d3d9Options.samplerAnisotropy;
key.setAniso(anisotropy);
float lodBias = bit::cast<float>(state[D3DSAMP_MIPMAPLODBIAS]);
lodBias += m_d3d9Options.samplerLodBias;
if (m_d3d9Options.clampNegativeLodBias)
lodBias = std::max(lodBias, 0.0f);
key.setLodRange(float(state[D3DSAMP_MAXMIPLEVEL]), 16.0f, lodBias);
}
NormalizeSamplerKey(key);
if (key.u.p.hasBorder)
DecodeD3DCOLOR(D3DCOLOR(state[D3DSAMP_BORDERCOLOR]), key.borderColor.float32);
auto samplerInfo = RemapStateSamplerShader(Sampler);
@ -6680,58 +6700,7 @@ namespace dxvk {
cKey = key
] (DxvkContext* ctx) {
VkShaderStageFlags stage = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
auto pair = m_samplers.find(cKey);
if (pair != m_samplers.end()) {
ctx->bindResourceSampler(stage, cSlot,
Rc<DxvkSampler>(pair->second));
return;
}
auto mipFilter = DecodeMipFilter(cKey.MipFilter);
DxvkSamplerKey info = { };
info.setFilter(
DecodeFilter(cKey.MinFilter),
DecodeFilter(cKey.MagFilter),
mipFilter.MipFilter);
info.setAddressModes(
DecodeAddressMode(cKey.AddressU),
DecodeAddressMode(cKey.AddressV),
DecodeAddressMode(cKey.AddressW));
info.setDepthCompare(cKey.Depth,
VK_COMPARE_OP_LESS_OR_EQUAL);
info.setAniso(cKey.MaxAnisotropy);
float lodBias = cKey.MipmapLodBias + m_d3d9Options.samplerLodBias;
if (m_d3d9Options.clampNegativeLodBias)
lodBias = std::max(lodBias, 0.0f);
info.setLodRange(
mipFilter.MipsEnabled ? float(cKey.MaxMipLevel) : 0.0f,
mipFilter.MipsEnabled ? FLT_MAX : 0.0f,
lodBias);
info.setLegacyCubeFilter(!m_d3d9Options.seamlessCubes);
DecodeD3DCOLOR(cKey.BorderColor, info.borderColor.float32);
try {
auto sampler = m_dxvkDevice->createSampler(info);
m_samplers.insert(std::make_pair(cKey, sampler));
ctx->bindResourceSampler(stage, cSlot, std::move(sampler));
m_samplerCount++;
}
catch (const DxvkError& e) {
Logger::err(e.message());
}
ctx->bindResourceSampler(stage, cSlot, m_dxvkDevice->createSampler(cKey));
});
}

View File

@ -22,7 +22,6 @@
#include "../dxso/dxso_options.h"
#include "../dxso/dxso_modinfo.h"
#include "d3d9_sampler.h"
#include "d3d9_fixed_function.h"
#include "d3d9_swvp_emu.h"
@ -979,10 +978,6 @@ namespace dxvk {
HRESULT InitialReset(D3DPRESENT_PARAMETERS* pPresentationParameters, D3DDISPLAYMODEEX* pFullscreenDisplayMode);
UINT GetSamplerCount() const {
return m_samplerCount.load();
}
D3D9MemoryAllocator* GetAllocator() {
return &m_memoryAllocator;
}
@ -1343,12 +1338,6 @@ namespace dxvk {
const D3D9Options m_d3d9Options;
DxsoOptions m_dxsoOptions;
std::unordered_map<
D3D9SamplerKey,
Rc<DxvkSampler>,
D3D9SamplerKeyHash,
D3D9SamplerKeyEq> m_samplers;
std::unordered_map<
DWORD,
Com<D3D9VertexDecl,
@ -1451,7 +1440,6 @@ namespace dxvk {
GpuFlushTracker m_flushTracker;
std::atomic<int64_t> m_availableMemory = { 0 };
std::atomic<int32_t> m_samplerCount = { 0 };
D3D9DeviceLostState m_deviceLostState = D3D9DeviceLostState::Ok;
HWND m_fullscreenWindow = NULL;

View File

@ -10,7 +10,8 @@ namespace dxvk::hud {
void HudSamplerCount::update(dxvk::high_resolution_clock::time_point time) {
m_samplerCount = str::format(m_device->GetSamplerCount());
DxvkSamplerStats stats = m_device->GetDXVKDevice()->getSamplerStats();
m_samplerCount = str::format(stats.totalCount);
}

View File

@ -1,44 +0,0 @@
#include "d3d9_sampler.h"
namespace dxvk {
size_t D3D9SamplerKeyHash::operator () (const D3D9SamplerKey& key) const {
DxvkHashState state;
std::hash<DWORD> dhash;
std::hash<D3DTEXTUREADDRESS> tahash;
std::hash<D3DTEXTUREFILTERTYPE> tfhash;
std::hash<float> fhash;
std::hash<bool> bhash;
state.add(tahash(key.AddressU));
state.add(tahash(key.AddressV));
state.add(tahash(key.AddressW));
state.add(tfhash(key.MagFilter));
state.add(tfhash(key.MinFilter));
state.add(tfhash(key.MipFilter));
state.add(dhash (key.MaxAnisotropy));
state.add(fhash (key.MipmapLodBias));
state.add(dhash (key.MaxMipLevel));
state.add(dhash (key.BorderColor));
state.add(bhash (key.Depth));
return state;
}
bool D3D9SamplerKeyEq::operator () (const D3D9SamplerKey& a, const D3D9SamplerKey& b) const {
return a.AddressU == b.AddressU
&& a.AddressV == b.AddressV
&& a.AddressW == b.AddressW
&& a.MagFilter == b.MagFilter
&& a.MinFilter == b.MinFilter
&& a.MipFilter == b.MipFilter
&& a.MaxAnisotropy == b.MaxAnisotropy
&& a.MipmapLodBias == b.MipmapLodBias
&& a.MaxMipLevel == b.MaxMipLevel
&& a.BorderColor == b.BorderColor
&& a.Depth == b.Depth;
}
}

View File

@ -1,75 +0,0 @@
#pragma once
#include "d3d9_include.h"
#include "d3d9_util.h"
#include "../dxvk/dxvk_hash.h"
#include "../util/util_math.h"
namespace dxvk {
struct D3D9SamplerKey {
D3DTEXTUREADDRESS AddressU;
D3DTEXTUREADDRESS AddressV;
D3DTEXTUREADDRESS AddressW;
D3DTEXTUREFILTERTYPE MagFilter;
D3DTEXTUREFILTERTYPE MinFilter;
D3DTEXTUREFILTERTYPE MipFilter;
DWORD MaxAnisotropy;
float MipmapLodBias;
DWORD MaxMipLevel;
D3DCOLOR BorderColor;
bool Depth;
};
struct D3D9SamplerKeyHash {
size_t operator () (const D3D9SamplerKey& key) const;
};
struct D3D9SamplerKeyEq {
bool operator () (const D3D9SamplerKey& a, const D3D9SamplerKey& b) const;
};
inline void NormalizeSamplerKey(D3D9SamplerKey& key) {
key.AddressU = std::clamp(key.AddressU, D3DTADDRESS_WRAP, D3DTADDRESS_MIRRORONCE);
key.AddressV = std::clamp(key.AddressV, D3DTADDRESS_WRAP, D3DTADDRESS_MIRRORONCE);
key.AddressW = std::clamp(key.AddressW, D3DTADDRESS_WRAP, D3DTADDRESS_MIRRORONCE);
bool hasAnisotropy = IsAnisotropic(key.MagFilter) || IsAnisotropic(key.MinFilter);
key.MagFilter = std::clamp(key.MagFilter, D3DTEXF_NONE, D3DTEXF_LINEAR);
key.MinFilter = std::clamp(key.MinFilter, D3DTEXF_NONE, D3DTEXF_LINEAR);
key.MipFilter = std::clamp(key.MipFilter, D3DTEXF_NONE, D3DTEXF_LINEAR);
key.MaxAnisotropy = hasAnisotropy
? std::clamp<DWORD>(key.MaxAnisotropy, 1, 16)
: 1;
if (key.MipFilter == D3DTEXF_NONE) {
// May as well try and keep slots down.
key.MipmapLodBias = 0;
}
else {
// Games also pass NAN here, this accounts for that.
if (unlikely(key.MipmapLodBias != key.MipmapLodBias))
key.MipmapLodBias = 0.0f;
// Clamp between -15.0f and 15.0f, matching mip limits of d3d9.
key.MipmapLodBias = std::clamp(key.MipmapLodBias, -15.0f, 15.0f);
// Round to the nearest .5
// Fixes sampler leaks in UE3 games w/ mip streaming
// eg. Borderlands 2
key.MipmapLodBias = std::round(key.MipmapLodBias * 2.0f) / 2.0f;
}
if (key.AddressU != D3DTADDRESS_BORDER
&& key.AddressV != D3DTADDRESS_BORDER
&& key.AddressW != D3DTADDRESS_BORDER) {
key.BorderColor = 0;
}
}
}

View File

@ -33,7 +33,6 @@ d3d9_src = [
'd3d9_multithread.cpp',
'd3d9_options.cpp',
'd3d9_stateblock.cpp',
'd3d9_sampler.cpp',
'd3d9_util.cpp',
'd3d9_initializer.cpp',
'd3d9_fixed_function.cpp',