mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-15 07:29:17 +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) {
|
void D3D9DeviceEx::BindSampler(DWORD Sampler) {
|
||||||
auto& state = m_state.samplerStates[Sampler];
|
auto& state = m_state.samplerStates[Sampler];
|
||||||
|
|
||||||
D3D9SamplerKey key;
|
D3DTEXTUREFILTERTYPE minFilter = D3DTEXTUREFILTERTYPE(state[D3DSAMP_MINFILTER]);
|
||||||
key.AddressU = D3DTEXTUREADDRESS(state[D3DSAMP_ADDRESSU]);
|
D3DTEXTUREFILTERTYPE magFilter = D3DTEXTUREFILTERTYPE(state[D3DSAMP_MAGFILTER]);
|
||||||
key.AddressV = D3DTEXTUREADDRESS(state[D3DSAMP_ADDRESSV]);
|
D3DTEXTUREFILTERTYPE mipFilter = D3DTEXTUREFILTERTYPE(state[D3DSAMP_MIPFILTER]);
|
||||||
key.AddressW = D3DTEXTUREADDRESS(state[D3DSAMP_ADDRESSW]);
|
|
||||||
key.MagFilter = D3DTEXTUREFILTERTYPE(state[D3DSAMP_MAGFILTER]);
|
DxvkSamplerKey key = { };
|
||||||
key.MinFilter = D3DTEXTUREFILTERTYPE(state[D3DSAMP_MINFILTER]);
|
|
||||||
key.MipFilter = D3DTEXTUREFILTERTYPE(state[D3DSAMP_MIPFILTER]);
|
key.setFilter(
|
||||||
key.MaxAnisotropy = state[D3DSAMP_MAXANISOTROPY];
|
DecodeFilter(minFilter),
|
||||||
key.MipmapLodBias = bit::cast<float>(state[D3DSAMP_MIPMAPLODBIAS]);
|
DecodeFilter(magFilter),
|
||||||
key.MaxMipLevel = state[D3DSAMP_MAXMIPLEVEL];
|
DecodeMipFilter(mipFilter).MipFilter);
|
||||||
key.BorderColor = D3DCOLOR(state[D3DSAMP_BORDERCOLOR]);
|
|
||||||
key.Depth = m_depthTextures & (1u << Sampler);
|
|
||||||
|
|
||||||
if (m_cubeTextures & (1u << Sampler)) {
|
if (m_cubeTextures & (1u << Sampler)) {
|
||||||
key.AddressU = D3DTADDRESS_CLAMP;
|
key.setAddressModes(
|
||||||
key.AddressV = D3DTADDRESS_CLAMP;
|
VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
|
||||||
key.AddressW = D3DTADDRESS_CLAMP;
|
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) {
|
key.setDepthCompare(m_depthTextures & (1u << Sampler), VK_COMPARE_OP_LESS_OR_EQUAL);
|
||||||
if (key.MagFilter == D3DTEXF_LINEAR)
|
|
||||||
key.MagFilter = D3DTEXF_ANISOTROPIC;
|
|
||||||
|
|
||||||
if (key.MinFilter == D3DTEXF_LINEAR)
|
if (mipFilter != D3DTEXF_NONE) {
|
||||||
key.MinFilter = D3DTEXF_ANISOTROPIC;
|
// 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);
|
auto samplerInfo = RemapStateSamplerShader(Sampler);
|
||||||
|
|
||||||
@ -6680,58 +6700,7 @@ namespace dxvk {
|
|||||||
cKey = key
|
cKey = key
|
||||||
] (DxvkContext* ctx) {
|
] (DxvkContext* ctx) {
|
||||||
VkShaderStageFlags stage = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
|
VkShaderStageFlags stage = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||||
|
ctx->bindResourceSampler(stage, cSlot, m_dxvkDevice->createSampler(cKey));
|
||||||
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());
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
#include "../dxso/dxso_options.h"
|
#include "../dxso/dxso_options.h"
|
||||||
#include "../dxso/dxso_modinfo.h"
|
#include "../dxso/dxso_modinfo.h"
|
||||||
|
|
||||||
#include "d3d9_sampler.h"
|
|
||||||
#include "d3d9_fixed_function.h"
|
#include "d3d9_fixed_function.h"
|
||||||
#include "d3d9_swvp_emu.h"
|
#include "d3d9_swvp_emu.h"
|
||||||
|
|
||||||
@ -979,10 +978,6 @@ namespace dxvk {
|
|||||||
|
|
||||||
HRESULT InitialReset(D3DPRESENT_PARAMETERS* pPresentationParameters, D3DDISPLAYMODEEX* pFullscreenDisplayMode);
|
HRESULT InitialReset(D3DPRESENT_PARAMETERS* pPresentationParameters, D3DDISPLAYMODEEX* pFullscreenDisplayMode);
|
||||||
|
|
||||||
UINT GetSamplerCount() const {
|
|
||||||
return m_samplerCount.load();
|
|
||||||
}
|
|
||||||
|
|
||||||
D3D9MemoryAllocator* GetAllocator() {
|
D3D9MemoryAllocator* GetAllocator() {
|
||||||
return &m_memoryAllocator;
|
return &m_memoryAllocator;
|
||||||
}
|
}
|
||||||
@ -1343,12 +1338,6 @@ namespace dxvk {
|
|||||||
const D3D9Options m_d3d9Options;
|
const D3D9Options m_d3d9Options;
|
||||||
DxsoOptions m_dxsoOptions;
|
DxsoOptions m_dxsoOptions;
|
||||||
|
|
||||||
std::unordered_map<
|
|
||||||
D3D9SamplerKey,
|
|
||||||
Rc<DxvkSampler>,
|
|
||||||
D3D9SamplerKeyHash,
|
|
||||||
D3D9SamplerKeyEq> m_samplers;
|
|
||||||
|
|
||||||
std::unordered_map<
|
std::unordered_map<
|
||||||
DWORD,
|
DWORD,
|
||||||
Com<D3D9VertexDecl,
|
Com<D3D9VertexDecl,
|
||||||
@ -1451,7 +1440,6 @@ namespace dxvk {
|
|||||||
GpuFlushTracker m_flushTracker;
|
GpuFlushTracker m_flushTracker;
|
||||||
|
|
||||||
std::atomic<int64_t> m_availableMemory = { 0 };
|
std::atomic<int64_t> m_availableMemory = { 0 };
|
||||||
std::atomic<int32_t> m_samplerCount = { 0 };
|
|
||||||
|
|
||||||
D3D9DeviceLostState m_deviceLostState = D3D9DeviceLostState::Ok;
|
D3D9DeviceLostState m_deviceLostState = D3D9DeviceLostState::Ok;
|
||||||
HWND m_fullscreenWindow = NULL;
|
HWND m_fullscreenWindow = NULL;
|
||||||
|
@ -10,7 +10,8 @@ namespace dxvk::hud {
|
|||||||
|
|
||||||
|
|
||||||
void HudSamplerCount::update(dxvk::high_resolution_clock::time_point time) {
|
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_multithread.cpp',
|
||||||
'd3d9_options.cpp',
|
'd3d9_options.cpp',
|
||||||
'd3d9_stateblock.cpp',
|
'd3d9_stateblock.cpp',
|
||||||
'd3d9_sampler.cpp',
|
|
||||||
'd3d9_util.cpp',
|
'd3d9_util.cpp',
|
||||||
'd3d9_initializer.cpp',
|
'd3d9_initializer.cpp',
|
||||||
'd3d9_fixed_function.cpp',
|
'd3d9_fixed_function.cpp',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user