mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-02 01:24:11 +01:00
[d3d9] Move building sampler key to CS thread
All this bit twiddling is a bit slow. Introduces another structure containing a minimal amount of sampler parameters taken from the raw D3D9 state.
This commit is contained in:
parent
543b5c7af8
commit
07dfeeb319
@ -6636,59 +6636,6 @@ namespace dxvk {
|
||||
|
||||
|
||||
void D3D9DeviceEx::BindSampler(DWORD Sampler) {
|
||||
auto& state = m_state.samplerStates[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));
|
||||
|
||||
if (m_cubeTextures & (1u << Sampler)) {
|
||||
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])));
|
||||
}
|
||||
|
||||
key.setDepthCompare(m_depthTextures & (1u << Sampler), VK_COMPARE_OP_LESS_OR_EQUAL);
|
||||
|
||||
if (mipFilter) {
|
||||
// Anisotropic filtering doesn't make any sense with only one mip
|
||||
uint32_t anisotropy = state[D3DSAMP_MAXANISOTROPY];
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (key.u.p.hasBorder)
|
||||
DecodeD3DCOLOR(D3DCOLOR(state[D3DSAMP_BORDERCOLOR]), key.borderColor.float32);
|
||||
|
||||
auto samplerInfo = RemapStateSamplerShader(Sampler);
|
||||
|
||||
const uint32_t slot = computeResourceSlotId(
|
||||
@ -6696,11 +6643,60 @@ namespace dxvk {
|
||||
samplerInfo.second);
|
||||
|
||||
EmitCs([this,
|
||||
cSlot = slot,
|
||||
cKey = key
|
||||
cSlot = slot,
|
||||
cState = D3D9SamplerInfo(m_state.samplerStates[Sampler]),
|
||||
cIsCube = bool(m_cubeTextures & (1u << Sampler)),
|
||||
cIsDepth = bool(m_depthTextures & (1u << Sampler))
|
||||
] (DxvkContext* ctx) {
|
||||
DxvkSamplerKey key = { };
|
||||
|
||||
key.setFilter(
|
||||
DecodeFilter(cState.minFilter),
|
||||
DecodeFilter(cState.magFilter),
|
||||
DecodeMipFilter(cState.mipFilter));
|
||||
|
||||
if (cIsCube) {
|
||||
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(cState.addressU),
|
||||
DecodeAddressMode(cState.addressV),
|
||||
DecodeAddressMode(cState.addressW));
|
||||
}
|
||||
|
||||
key.setDepthCompare(cIsDepth, VK_COMPARE_OP_LESS_OR_EQUAL);
|
||||
|
||||
if (cState.mipFilter) {
|
||||
// Anisotropic filtering doesn't make any sense with only one mip
|
||||
uint32_t anisotropy = cState.maxAnisotropy;
|
||||
|
||||
if (cState.minFilter != D3DTEXF_ANISOTROPIC)
|
||||
anisotropy = 0u;
|
||||
|
||||
if (m_d3d9Options.samplerAnisotropy != -1 && cState.minFilter > D3DTEXF_POINT)
|
||||
anisotropy = m_d3d9Options.samplerAnisotropy;
|
||||
|
||||
key.setAniso(anisotropy);
|
||||
|
||||
float lodBias = cState.mipLodBias;
|
||||
lodBias += m_d3d9Options.samplerLodBias;
|
||||
|
||||
if (m_d3d9Options.clampNegativeLodBias)
|
||||
lodBias = std::max(lodBias, 0.0f);
|
||||
|
||||
key.setLodRange(float(cState.maxMipLevel), 16.0f, lodBias);
|
||||
}
|
||||
|
||||
if (key.u.p.hasBorder)
|
||||
DecodeD3DCOLOR(cState.borderColor, key.borderColor.float32);
|
||||
|
||||
VkShaderStageFlags stage = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
ctx->bindResourceSampler(stage, cSlot, m_dxvkDevice->createSampler(cKey));
|
||||
ctx->bindResourceSampler(stage, cSlot, m_dxvkDevice->createSampler(key));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -227,6 +227,33 @@ namespace dxvk {
|
||||
T m_data;
|
||||
};
|
||||
|
||||
struct D3D9SamplerInfo {
|
||||
D3D9SamplerInfo() = default;
|
||||
|
||||
D3D9SamplerInfo(const std::array<DWORD, SamplerStateCount>& state)
|
||||
: addressU(D3DTEXTUREADDRESS(state[D3DSAMP_ADDRESSU]))
|
||||
, addressV(D3DTEXTUREADDRESS(state[D3DSAMP_ADDRESSV]))
|
||||
, addressW(D3DTEXTUREADDRESS(state[D3DSAMP_ADDRESSW]))
|
||||
, borderColor(D3DCOLOR(state[D3DSAMP_BORDERCOLOR]))
|
||||
, magFilter(D3DTEXTUREFILTERTYPE(state[D3DSAMP_MAGFILTER]))
|
||||
, minFilter(D3DTEXTUREFILTERTYPE(state[D3DSAMP_MINFILTER]))
|
||||
, mipFilter(D3DTEXTUREFILTERTYPE(state[D3DSAMP_MIPFILTER]))
|
||||
, mipLodBias(bit::cast<float>(state[D3DSAMP_MIPMAPLODBIAS]))
|
||||
, maxMipLevel(state[D3DSAMP_MAXMIPLEVEL])
|
||||
, maxAnisotropy(state[D3DSAMP_MAXMIPLEVEL]) { }
|
||||
|
||||
D3DTEXTUREADDRESS addressU;
|
||||
D3DTEXTUREADDRESS addressV;
|
||||
D3DTEXTUREADDRESS addressW;
|
||||
D3DCOLOR borderColor;
|
||||
D3DTEXTUREFILTERTYPE magFilter;
|
||||
D3DTEXTUREFILTERTYPE minFilter;
|
||||
D3DTEXTUREFILTERTYPE mipFilter;
|
||||
float mipLodBias;
|
||||
DWORD maxMipLevel;
|
||||
DWORD maxAnisotropy;
|
||||
};
|
||||
|
||||
template <template <typename T> typename ItemType>
|
||||
struct D3D9State {
|
||||
D3D9State();
|
||||
|
Loading…
Reference in New Issue
Block a user