mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-02 10:24:12 +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) {
|
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);
|
auto samplerInfo = RemapStateSamplerShader(Sampler);
|
||||||
|
|
||||||
const uint32_t slot = computeResourceSlotId(
|
const uint32_t slot = computeResourceSlotId(
|
||||||
@ -6697,10 +6644,59 @@ namespace dxvk {
|
|||||||
|
|
||||||
EmitCs([this,
|
EmitCs([this,
|
||||||
cSlot = slot,
|
cSlot = slot,
|
||||||
cKey = key
|
cState = D3D9SamplerInfo(m_state.samplerStates[Sampler]),
|
||||||
|
cIsCube = bool(m_cubeTextures & (1u << Sampler)),
|
||||||
|
cIsDepth = bool(m_depthTextures & (1u << Sampler))
|
||||||
] (DxvkContext* ctx) {
|
] (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;
|
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;
|
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>
|
template <template <typename T> typename ItemType>
|
||||||
struct D3D9State {
|
struct D3D9State {
|
||||||
D3D9State();
|
D3D9State();
|
||||||
|
Loading…
Reference in New Issue
Block a user