mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-31 01:59:52 -06:00
VideoCommon: Expose SamplerState to shaders
The benefit to exposing this over the raw BP state is that adjustments Dolphin makes, such as LOD biases from arbitrary mipmap detection, will work properly.
This commit is contained in:
@ -303,43 +303,43 @@ StateCache::~StateCache() = default;
|
||||
ID3D11SamplerState* StateCache::Get(SamplerState state)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(m_lock);
|
||||
auto it = m_sampler.find(state.hex);
|
||||
auto it = m_sampler.find(state);
|
||||
if (it != m_sampler.end())
|
||||
return it->second.Get();
|
||||
|
||||
D3D11_SAMPLER_DESC sampdc = CD3D11_SAMPLER_DESC(CD3D11_DEFAULT());
|
||||
if (state.mipmap_filter == SamplerState::Filter::Linear)
|
||||
if (state.tm0.mipmap_filter == FilterMode::Linear)
|
||||
{
|
||||
if (state.min_filter == SamplerState::Filter::Linear)
|
||||
sampdc.Filter = (state.mag_filter == SamplerState::Filter::Linear) ?
|
||||
if (state.tm0.min_filter == FilterMode::Linear)
|
||||
sampdc.Filter = (state.tm0.mag_filter == FilterMode::Linear) ?
|
||||
D3D11_FILTER_MIN_MAG_MIP_LINEAR :
|
||||
D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR;
|
||||
else
|
||||
sampdc.Filter = (state.mag_filter == SamplerState::Filter::Linear) ?
|
||||
sampdc.Filter = (state.tm0.mag_filter == FilterMode::Linear) ?
|
||||
D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR :
|
||||
D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (state.min_filter == SamplerState::Filter::Linear)
|
||||
sampdc.Filter = (state.mag_filter == SamplerState::Filter::Linear) ?
|
||||
if (state.tm0.min_filter == FilterMode::Linear)
|
||||
sampdc.Filter = (state.tm0.mag_filter == FilterMode::Linear) ?
|
||||
D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT :
|
||||
D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT;
|
||||
else
|
||||
sampdc.Filter = (state.mag_filter == SamplerState::Filter::Linear) ?
|
||||
sampdc.Filter = (state.tm0.mag_filter == FilterMode::Linear) ?
|
||||
D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT :
|
||||
D3D11_FILTER_MIN_MAG_MIP_POINT;
|
||||
}
|
||||
|
||||
static constexpr std::array<D3D11_TEXTURE_ADDRESS_MODE, 3> address_modes = {
|
||||
{D3D11_TEXTURE_ADDRESS_CLAMP, D3D11_TEXTURE_ADDRESS_WRAP, D3D11_TEXTURE_ADDRESS_MIRROR}};
|
||||
sampdc.AddressU = address_modes[static_cast<u32>(state.wrap_u.Value())];
|
||||
sampdc.AddressV = address_modes[static_cast<u32>(state.wrap_v.Value())];
|
||||
sampdc.MaxLOD = state.max_lod / 16.f;
|
||||
sampdc.MinLOD = state.min_lod / 16.f;
|
||||
sampdc.MipLODBias = (s32)state.lod_bias / 256.f;
|
||||
sampdc.AddressU = address_modes[static_cast<u32>(state.tm0.wrap_u.Value())];
|
||||
sampdc.AddressV = address_modes[static_cast<u32>(state.tm0.wrap_v.Value())];
|
||||
sampdc.MaxLOD = state.tm1.max_lod / 16.f;
|
||||
sampdc.MinLOD = state.tm1.min_lod / 16.f;
|
||||
sampdc.MipLODBias = state.tm0.lod_bias / 256.f;
|
||||
|
||||
if (state.anisotropic_filtering)
|
||||
if (state.tm0.anisotropic_filtering)
|
||||
{
|
||||
sampdc.Filter = D3D11_FILTER_ANISOTROPIC;
|
||||
sampdc.MaxAnisotropy = 1u << g_ActiveConfig.iMaxAnisotropy;
|
||||
@ -348,7 +348,7 @@ ID3D11SamplerState* StateCache::Get(SamplerState state)
|
||||
ComPtr<ID3D11SamplerState> res;
|
||||
HRESULT hr = D3D::device->CreateSamplerState(&sampdc, res.GetAddressOf());
|
||||
CHECK(SUCCEEDED(hr), "Creating D3D sampler state failed");
|
||||
return m_sampler.emplace(state.hex, std::move(res)).first->second.Get();
|
||||
return m_sampler.emplace(state, std::move(res)).first->second.Get();
|
||||
}
|
||||
|
||||
ID3D11BlendState* StateCache::Get(BlendingState state)
|
||||
|
@ -37,7 +37,7 @@ private:
|
||||
std::unordered_map<u32, ComPtr<ID3D11DepthStencilState>> m_depth;
|
||||
std::unordered_map<u32, ComPtr<ID3D11RasterizerState>> m_raster;
|
||||
std::unordered_map<u32, ComPtr<ID3D11BlendState>> m_blend;
|
||||
std::unordered_map<SamplerState::StorageType, ComPtr<ID3D11SamplerState>> m_sampler;
|
||||
std::unordered_map<SamplerState, ComPtr<ID3D11SamplerState>> m_sampler;
|
||||
std::mutex m_lock;
|
||||
};
|
||||
|
||||
|
@ -85,32 +85,32 @@ SamplerHeapManager::~SamplerHeapManager() = default;
|
||||
|
||||
static void GetD3DSamplerDesc(D3D12_SAMPLER_DESC* desc, const SamplerState& state)
|
||||
{
|
||||
if (state.mipmap_filter == SamplerState::Filter::Linear)
|
||||
if (state.tm0.mipmap_filter == FilterMode::Linear)
|
||||
{
|
||||
if (state.min_filter == SamplerState::Filter::Linear)
|
||||
if (state.tm0.min_filter == FilterMode::Linear)
|
||||
{
|
||||
desc->Filter = (state.mag_filter == SamplerState::Filter::Linear) ?
|
||||
desc->Filter = (state.tm0.mag_filter == FilterMode::Linear) ?
|
||||
D3D12_FILTER_MIN_MAG_MIP_LINEAR :
|
||||
D3D12_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR;
|
||||
}
|
||||
else
|
||||
{
|
||||
desc->Filter = (state.mag_filter == SamplerState::Filter::Linear) ?
|
||||
desc->Filter = (state.tm0.mag_filter == FilterMode::Linear) ?
|
||||
D3D12_FILTER_MIN_POINT_MAG_MIP_LINEAR :
|
||||
D3D12_FILTER_MIN_MAG_POINT_MIP_LINEAR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (state.min_filter == SamplerState::Filter::Linear)
|
||||
if (state.tm0.min_filter == FilterMode::Linear)
|
||||
{
|
||||
desc->Filter = (state.mag_filter == SamplerState::Filter::Linear) ?
|
||||
desc->Filter = (state.tm0.mag_filter == FilterMode::Linear) ?
|
||||
D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT :
|
||||
D3D12_FILTER_MIN_LINEAR_MAG_MIP_POINT;
|
||||
}
|
||||
else
|
||||
{
|
||||
desc->Filter = (state.mag_filter == SamplerState::Filter::Linear) ?
|
||||
desc->Filter = (state.tm0.mag_filter == FilterMode::Linear) ?
|
||||
D3D12_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT :
|
||||
D3D12_FILTER_MIN_MAG_MIP_POINT;
|
||||
}
|
||||
@ -119,15 +119,15 @@ static void GetD3DSamplerDesc(D3D12_SAMPLER_DESC* desc, const SamplerState& stat
|
||||
static constexpr std::array<D3D12_TEXTURE_ADDRESS_MODE, 3> address_modes = {
|
||||
{D3D12_TEXTURE_ADDRESS_MODE_CLAMP, D3D12_TEXTURE_ADDRESS_MODE_WRAP,
|
||||
D3D12_TEXTURE_ADDRESS_MODE_MIRROR}};
|
||||
desc->AddressU = address_modes[static_cast<u32>(state.wrap_u.Value())];
|
||||
desc->AddressV = address_modes[static_cast<u32>(state.wrap_v.Value())];
|
||||
desc->AddressU = address_modes[static_cast<u32>(state.tm0.wrap_u.Value())];
|
||||
desc->AddressV = address_modes[static_cast<u32>(state.tm0.wrap_v.Value())];
|
||||
desc->AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
|
||||
desc->MaxLOD = state.max_lod / 16.f;
|
||||
desc->MinLOD = state.min_lod / 16.f;
|
||||
desc->MipLODBias = static_cast<s32>(state.lod_bias) / 256.f;
|
||||
desc->MaxLOD = state.tm1.max_lod / 16.f;
|
||||
desc->MinLOD = state.tm1.min_lod / 16.f;
|
||||
desc->MipLODBias = static_cast<s32>(state.tm0.lod_bias) / 256.f;
|
||||
desc->ComparisonFunc = D3D12_COMPARISON_FUNC_NEVER;
|
||||
|
||||
if (state.anisotropic_filtering)
|
||||
if (state.tm0.anisotropic_filtering)
|
||||
{
|
||||
desc->Filter = D3D12_FILTER_ANISOTROPIC;
|
||||
desc->MaxAnisotropy = 1u << g_ActiveConfig.iMaxAnisotropy;
|
||||
@ -136,7 +136,7 @@ static void GetD3DSamplerDesc(D3D12_SAMPLER_DESC* desc, const SamplerState& stat
|
||||
|
||||
bool SamplerHeapManager::Lookup(const SamplerState& ss, D3D12_CPU_DESCRIPTOR_HANDLE* handle)
|
||||
{
|
||||
const auto it = m_sampler_map.find(ss.hex);
|
||||
const auto it = m_sampler_map.find(ss);
|
||||
if (it != m_sampler_map.end())
|
||||
{
|
||||
*handle = it->second;
|
||||
@ -158,7 +158,7 @@ bool SamplerHeapManager::Lookup(const SamplerState& ss, D3D12_CPU_DESCRIPTOR_HAN
|
||||
m_current_offset * m_descriptor_increment_size};
|
||||
g_dx_context->GetDevice()->CreateSampler(&desc, new_handle);
|
||||
|
||||
m_sampler_map.emplace(ss.hex, new_handle);
|
||||
m_sampler_map.emplace(ss, new_handle);
|
||||
m_current_offset++;
|
||||
*handle = new_handle;
|
||||
return true;
|
||||
|
@ -68,6 +68,6 @@ private:
|
||||
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE m_heap_base_cpu{};
|
||||
|
||||
std::unordered_map<SamplerState::StorageType, D3D12_CPU_DESCRIPTOR_HANDLE> m_sampler_map;
|
||||
std::unordered_map<SamplerState, D3D12_CPU_DESCRIPTOR_HANDLE> m_sampler_map;
|
||||
};
|
||||
} // namespace DX12
|
||||
|
@ -71,16 +71,16 @@ void SamplerCache::InvalidateBinding(u32 stage)
|
||||
void SamplerCache::SetParameters(GLuint sampler_id, const SamplerState& params)
|
||||
{
|
||||
GLenum min_filter;
|
||||
GLenum mag_filter = (params.mag_filter == SamplerState::Filter::Point) ? GL_NEAREST : GL_LINEAR;
|
||||
if (params.mipmap_filter == SamplerState::Filter::Linear)
|
||||
GLenum mag_filter = (params.tm0.mag_filter == FilterMode::Near) ? GL_NEAREST : GL_LINEAR;
|
||||
if (params.tm0.mipmap_filter == FilterMode::Linear)
|
||||
{
|
||||
min_filter = (params.min_filter == SamplerState::Filter::Point) ? GL_NEAREST_MIPMAP_LINEAR :
|
||||
GL_LINEAR_MIPMAP_LINEAR;
|
||||
min_filter = (params.tm0.min_filter == FilterMode::Near) ? GL_NEAREST_MIPMAP_LINEAR :
|
||||
GL_LINEAR_MIPMAP_LINEAR;
|
||||
}
|
||||
else
|
||||
{
|
||||
min_filter = (params.min_filter == SamplerState::Filter::Point) ? GL_NEAREST_MIPMAP_NEAREST :
|
||||
GL_LINEAR_MIPMAP_NEAREST;
|
||||
min_filter = (params.tm0.min_filter == FilterMode::Near) ? GL_NEAREST_MIPMAP_NEAREST :
|
||||
GL_LINEAR_MIPMAP_NEAREST;
|
||||
}
|
||||
|
||||
glSamplerParameteri(sampler_id, GL_TEXTURE_MIN_FILTER, min_filter);
|
||||
@ -90,17 +90,17 @@ void SamplerCache::SetParameters(GLuint sampler_id, const SamplerState& params)
|
||||
{GL_CLAMP_TO_EDGE, GL_REPEAT, GL_MIRRORED_REPEAT}};
|
||||
|
||||
glSamplerParameteri(sampler_id, GL_TEXTURE_WRAP_S,
|
||||
address_modes[static_cast<u32>(params.wrap_u.Value())]);
|
||||
address_modes[static_cast<u32>(params.tm0.wrap_u.Value())]);
|
||||
glSamplerParameteri(sampler_id, GL_TEXTURE_WRAP_T,
|
||||
address_modes[static_cast<u32>(params.wrap_v.Value())]);
|
||||
address_modes[static_cast<u32>(params.tm0.wrap_v.Value())]);
|
||||
|
||||
glSamplerParameterf(sampler_id, GL_TEXTURE_MIN_LOD, params.min_lod / 16.f);
|
||||
glSamplerParameterf(sampler_id, GL_TEXTURE_MAX_LOD, params.max_lod / 16.f);
|
||||
glSamplerParameterf(sampler_id, GL_TEXTURE_MIN_LOD, params.tm1.min_lod / 16.f);
|
||||
glSamplerParameterf(sampler_id, GL_TEXTURE_MAX_LOD, params.tm1.max_lod / 16.f);
|
||||
|
||||
if (!static_cast<Renderer*>(g_renderer.get())->IsGLES())
|
||||
glSamplerParameterf(sampler_id, GL_TEXTURE_LOD_BIAS, params.lod_bias / 256.f);
|
||||
glSamplerParameterf(sampler_id, GL_TEXTURE_LOD_BIAS, params.tm0.lod_bias / 256.f);
|
||||
|
||||
if (params.anisotropic_filtering && g_ogl_config.bSupportsAniso)
|
||||
if (params.tm0.anisotropic_filtering && g_ogl_config.bSupportsAniso)
|
||||
{
|
||||
glSamplerParameterf(sampler_id, GL_TEXTURE_MAX_ANISOTROPY_EXT,
|
||||
static_cast<float>(1 << g_ActiveConfig.iMaxAnisotropy));
|
||||
|
@ -315,28 +315,28 @@ VkSampler ObjectCache::GetSampler(const SamplerState& info)
|
||||
VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT}};
|
||||
|
||||
VkSamplerCreateInfo create_info = {
|
||||
VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType
|
||||
nullptr, // const void* pNext
|
||||
0, // VkSamplerCreateFlags flags
|
||||
filters[static_cast<u32>(info.mag_filter.Value())], // VkFilter magFilter
|
||||
filters[static_cast<u32>(info.min_filter.Value())], // VkFilter minFilter
|
||||
mipmap_modes[static_cast<u32>(info.mipmap_filter.Value())], // VkSamplerMipmapMode mipmapMode
|
||||
address_modes[static_cast<u32>(info.wrap_u.Value())], // VkSamplerAddressMode addressModeU
|
||||
address_modes[static_cast<u32>(info.wrap_v.Value())], // VkSamplerAddressMode addressModeV
|
||||
VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW
|
||||
info.lod_bias / 256.0f, // float mipLodBias
|
||||
VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType
|
||||
nullptr, // const void* pNext
|
||||
0, // VkSamplerCreateFlags flags
|
||||
filters[u32(info.tm0.mag_filter.Value())], // VkFilter magFilter
|
||||
filters[u32(info.tm0.min_filter.Value())], // VkFilter minFilter
|
||||
mipmap_modes[u32(info.tm0.mipmap_filter.Value())], // VkSamplerMipmapMode mipmapMode
|
||||
address_modes[u32(info.tm0.wrap_u.Value())], // VkSamplerAddressMode addressModeU
|
||||
address_modes[u32(info.tm0.wrap_v.Value())], // VkSamplerAddressMode addressModeV
|
||||
VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW
|
||||
info.tm0.lod_bias / 256.0f, // float mipLodBias
|
||||
VK_FALSE, // VkBool32 anisotropyEnable
|
||||
0.0f, // float maxAnisotropy
|
||||
VK_FALSE, // VkBool32 compareEnable
|
||||
VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp
|
||||
info.min_lod / 16.0f, // float minLod
|
||||
info.max_lod / 16.0f, // float maxLod
|
||||
info.tm1.min_lod / 16.0f, // float minLod
|
||||
info.tm1.max_lod / 16.0f, // float maxLod
|
||||
VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // VkBorderColor borderColor
|
||||
VK_FALSE // VkBool32 unnormalizedCoordinates
|
||||
};
|
||||
|
||||
// Can we use anisotropic filtering with this sampler?
|
||||
if (info.anisotropic_filtering && g_vulkan_context->SupportsAnisotropicFiltering())
|
||||
if (info.tm0.anisotropic_filtering && g_vulkan_context->SupportsAnisotropicFiltering())
|
||||
{
|
||||
// Cap anisotropy to device limits.
|
||||
create_info.anisotropyEnable = VK_TRUE;
|
||||
|
@ -49,7 +49,7 @@ Renderer::Renderer(std::unique_ptr<SwapChain> swap_chain, float backbuffer_scale
|
||||
{
|
||||
UpdateActiveConfig();
|
||||
for (SamplerState& m_sampler_state : m_sampler_states)
|
||||
m_sampler_state.hex = RenderState::GetPointSamplerState().hex;
|
||||
m_sampler_state = RenderState::GetPointSamplerState();
|
||||
}
|
||||
|
||||
Renderer::~Renderer() = default;
|
||||
@ -545,7 +545,7 @@ void Renderer::SetTexture(u32 index, const AbstractTexture* texture)
|
||||
void Renderer::SetSamplerState(u32 index, const SamplerState& state)
|
||||
{
|
||||
// Skip lookup if the state hasn't changed.
|
||||
if (m_sampler_states[index].hex == state.hex)
|
||||
if (m_sampler_states[index] == state)
|
||||
return;
|
||||
|
||||
// Look up new state and replace in state tracker.
|
||||
@ -557,7 +557,7 @@ void Renderer::SetSamplerState(u32 index, const SamplerState& state)
|
||||
}
|
||||
|
||||
StateTracker::GetInstance()->SetSampler(index, sampler);
|
||||
m_sampler_states[index].hex = state.hex;
|
||||
m_sampler_states[index] = state;
|
||||
}
|
||||
|
||||
void Renderer::SetComputeImageTexture(AbstractTexture* texture, bool read, bool write)
|
||||
@ -588,7 +588,7 @@ void Renderer::ResetSamplerStates()
|
||||
// Invalidate all sampler states, next draw will re-initialize them.
|
||||
for (u32 i = 0; i < m_sampler_states.size(); i++)
|
||||
{
|
||||
m_sampler_states[i].hex = RenderState::GetPointSamplerState().hex;
|
||||
m_sampler_states[i] = RenderState::GetPointSamplerState();
|
||||
StateTracker::GetInstance()->SetSampler(i, g_object_cache->GetPointSampler());
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user