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:
parent
707ddd63a1
commit
c7dab6a442
@ -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));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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',
|
||||
|
Loading…
x
Reference in New Issue
Block a user