mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-25 07:09:48 -06:00
VideoBackends: Move SamplerState to common
This commit is contained in:
@ -132,20 +132,4 @@ union MultisamplingState
|
||||
u32 hex;
|
||||
};
|
||||
|
||||
// Sampler info
|
||||
union SamplerState
|
||||
{
|
||||
BitField<0, 1, VkFilter> min_filter;
|
||||
BitField<1, 1, VkFilter> mag_filter;
|
||||
BitField<2, 1, VkSamplerMipmapMode> mipmap_mode;
|
||||
BitField<3, 2, VkSamplerAddressMode> wrap_u;
|
||||
BitField<5, 2, VkSamplerAddressMode> wrap_v;
|
||||
BitField<7, 8, u32> min_lod;
|
||||
BitField<15, 8, u32> max_lod;
|
||||
BitField<23, 8, s32> lod_bias;
|
||||
BitField<31, 1, u32> enable_anisotropic_filtering;
|
||||
|
||||
u32 bits;
|
||||
};
|
||||
|
||||
} // namespace Vulkan
|
||||
|
@ -312,29 +312,36 @@ VkSampler ObjectCache::GetSampler(const SamplerState& info)
|
||||
if (iter != m_sampler_cache.end())
|
||||
return iter->second;
|
||||
|
||||
static constexpr std::array<VkFilter, 4> filters = {{VK_FILTER_NEAREST, VK_FILTER_LINEAR}};
|
||||
static constexpr std::array<VkSamplerMipmapMode, 2> mipmap_modes = {
|
||||
{VK_SAMPLER_MIPMAP_MODE_NEAREST, VK_SAMPLER_MIPMAP_MODE_LINEAR}};
|
||||
static constexpr std::array<VkSamplerAddressMode, 4> address_modes = {
|
||||
{VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_REPEAT,
|
||||
VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT}};
|
||||
|
||||
VkSamplerCreateInfo create_info = {
|
||||
VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType
|
||||
nullptr, // const void* pNext
|
||||
0, // VkSamplerCreateFlags flags
|
||||
info.mag_filter, // VkFilter magFilter
|
||||
info.min_filter, // VkFilter minFilter
|
||||
info.mipmap_mode, // VkSamplerMipmapMode mipmapMode
|
||||
info.wrap_u, // VkSamplerAddressMode addressModeU
|
||||
info.wrap_v, // VkSamplerAddressMode addressModeV
|
||||
VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW
|
||||
static_cast<float>(info.lod_bias / 32.0f), // float mipLodBias
|
||||
VK_FALSE, // VkBool32 anisotropyEnable
|
||||
0.0f, // float maxAnisotropy
|
||||
VK_FALSE, // VkBool32 compareEnable
|
||||
VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp
|
||||
static_cast<float>(info.min_lod / 16.0f), // float minLod
|
||||
static_cast<float>(info.max_lod / 16.0f), // float maxLod
|
||||
VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // VkBorderColor borderColor
|
||||
VK_FALSE // VkBool32 unnormalizedCoordinates
|
||||
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 / 32.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
|
||||
VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // VkBorderColor borderColor
|
||||
VK_FALSE // VkBool32 unnormalizedCoordinates
|
||||
};
|
||||
|
||||
// Can we use anisotropic filtering with this sampler?
|
||||
if (info.enable_anisotropic_filtering && g_vulkan_context->SupportsAnisotropicFiltering())
|
||||
if (info.anisotropic_filtering && g_vulkan_context->SupportsAnisotropicFiltering())
|
||||
{
|
||||
// Cap anisotropy to device limits.
|
||||
create_info.anisotropyEnable = VK_TRUE;
|
||||
|
@ -52,10 +52,8 @@ Renderer::Renderer(std::unique_ptr<SwapChain> swap_chain)
|
||||
m_swap_chain(std::move(swap_chain))
|
||||
{
|
||||
UpdateActiveConfig();
|
||||
|
||||
// Set to something invalid, forcing all states to be re-initialized.
|
||||
for (size_t i = 0; i < m_sampler_states.size(); i++)
|
||||
m_sampler_states[i].bits = std::numeric_limits<decltype(m_sampler_states[i].bits)>::max();
|
||||
m_sampler_states[i].hex = RenderState::GetPointSamplerState().hex;
|
||||
}
|
||||
|
||||
Renderer::~Renderer()
|
||||
@ -1282,65 +1280,22 @@ void Renderer::SetBlendingState(const BlendingState& state)
|
||||
StateTracker::GetInstance()->SetBlendState(state);
|
||||
}
|
||||
|
||||
void Renderer::SetSamplerState(int stage, int texindex, bool custom_tex)
|
||||
void Renderer::SetSamplerState(u32 index, const SamplerState& state)
|
||||
{
|
||||
const FourTexUnits& tex = bpmem.tex[texindex];
|
||||
const TexMode0& tm0 = tex.texMode0[stage];
|
||||
const TexMode1& tm1 = tex.texMode1[stage];
|
||||
SamplerState new_state = {};
|
||||
|
||||
if (g_ActiveConfig.bForceFiltering)
|
||||
{
|
||||
new_state.min_filter = VK_FILTER_LINEAR;
|
||||
new_state.mag_filter = VK_FILTER_LINEAR;
|
||||
new_state.mipmap_mode = SamplerCommon::AreBpTexMode0MipmapsEnabled(tm0) ?
|
||||
VK_SAMPLER_MIPMAP_MODE_LINEAR :
|
||||
VK_SAMPLER_MIPMAP_MODE_NEAREST;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Constants for these?
|
||||
new_state.min_filter = (tm0.min_filter & 4) != 0 ? VK_FILTER_LINEAR : VK_FILTER_NEAREST;
|
||||
new_state.mipmap_mode = SamplerCommon::AreBpTexMode0MipmapsEnabled(tm0) ?
|
||||
VK_SAMPLER_MIPMAP_MODE_LINEAR :
|
||||
VK_SAMPLER_MIPMAP_MODE_NEAREST;
|
||||
new_state.mag_filter = tm0.mag_filter != 0 ? VK_FILTER_LINEAR : VK_FILTER_NEAREST;
|
||||
}
|
||||
|
||||
// If mipmaps are disabled, clamp min/max lod
|
||||
new_state.max_lod = SamplerCommon::AreBpTexMode0MipmapsEnabled(tm0) ? tm1.max_lod : 0;
|
||||
new_state.min_lod = std::min(new_state.max_lod.Value(), tm1.min_lod);
|
||||
new_state.lod_bias = SamplerCommon::AreBpTexMode0MipmapsEnabled(tm0) ? tm0.lod_bias : 0;
|
||||
|
||||
// Custom textures may have a greater number of mips
|
||||
if (custom_tex)
|
||||
new_state.max_lod = 255;
|
||||
|
||||
// Address modes
|
||||
static const VkSamplerAddressMode address_modes[] = {
|
||||
VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_REPEAT,
|
||||
VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, VK_SAMPLER_ADDRESS_MODE_REPEAT};
|
||||
new_state.wrap_u = address_modes[tm0.wrap_s];
|
||||
new_state.wrap_v = address_modes[tm0.wrap_t];
|
||||
|
||||
// Only use anisotropic filtering for textures that would be linearly filtered.
|
||||
new_state.enable_anisotropic_filtering = SamplerCommon::IsBpTexMode0PointFiltering(tm0) ? 0 : 1;
|
||||
|
||||
// Skip lookup if the state hasn't changed.
|
||||
size_t bind_index = (texindex * 4) + stage;
|
||||
if (m_sampler_states[bind_index].bits == new_state.bits)
|
||||
if (m_sampler_states[index].hex == state.hex)
|
||||
return;
|
||||
|
||||
// Look up new state and replace in state tracker.
|
||||
VkSampler sampler = g_object_cache->GetSampler(new_state);
|
||||
VkSampler sampler = g_object_cache->GetSampler(state);
|
||||
if (sampler == VK_NULL_HANDLE)
|
||||
{
|
||||
ERROR_LOG(VIDEO, "Failed to create sampler");
|
||||
sampler = g_object_cache->GetPointSampler();
|
||||
}
|
||||
|
||||
StateTracker::GetInstance()->SetSampler(bind_index, sampler);
|
||||
m_sampler_states[bind_index].bits = new_state.bits;
|
||||
StateTracker::GetInstance()->SetSampler(index, sampler);
|
||||
m_sampler_states[index].hex = state.hex;
|
||||
}
|
||||
|
||||
void Renderer::ResetSamplerStates()
|
||||
@ -1352,7 +1307,7 @@ void Renderer::ResetSamplerStates()
|
||||
// Invalidate all sampler states, next draw will re-initialize them.
|
||||
for (size_t i = 0; i < m_sampler_states.size(); i++)
|
||||
{
|
||||
m_sampler_states[i].bits = std::numeric_limits<decltype(m_sampler_states[i].bits)>::max();
|
||||
m_sampler_states[i].hex = RenderState::GetPointSamplerState().hex;
|
||||
StateTracker::GetInstance()->SetSampler(i, g_object_cache->GetPointSampler());
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,7 @@ public:
|
||||
void SetScissorRect(const EFBRectangle& rc) override;
|
||||
void SetRasterizationState(const RasterizationState& state) override;
|
||||
void SetDepthState(const DepthState& state) override;
|
||||
void SetSamplerState(int stage, int texindex, bool custom_tex) override;
|
||||
void SetSamplerState(u32 index, const SamplerState& state) override;
|
||||
void SetInterlacingMode() override;
|
||||
void SetViewport() override;
|
||||
|
||||
|
@ -977,18 +977,6 @@ std::string ShaderCache::GetUtilityShaderHeader() const
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
// Comparison operators for PipelineInfos
|
||||
// Since these all boil down to POD types, we can just memcmp the entire thing for speed
|
||||
// The is_trivially_copyable check fails on MSVC due to BitField.
|
||||
// TODO: Can we work around this any way?
|
||||
#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 5 && !defined(_MSC_VER)
|
||||
static_assert(std::has_trivial_copy_constructor<PipelineInfo>::value,
|
||||
"PipelineInfo is trivially copyable");
|
||||
#elif !defined(_MSC_VER)
|
||||
static_assert(std::is_trivially_copyable<PipelineInfo>::value,
|
||||
"PipelineInfo is trivially copyable");
|
||||
#endif
|
||||
|
||||
std::size_t PipelineInfoHash::operator()(const PipelineInfo& key) const
|
||||
{
|
||||
return static_cast<std::size_t>(XXH64(&key, sizeof(key), 0));
|
||||
@ -1014,26 +1002,6 @@ bool operator>(const PipelineInfo& lhs, const PipelineInfo& rhs)
|
||||
return std::memcmp(&lhs, &rhs, sizeof(lhs)) > 0;
|
||||
}
|
||||
|
||||
bool operator==(const SamplerState& lhs, const SamplerState& rhs)
|
||||
{
|
||||
return lhs.bits == rhs.bits;
|
||||
}
|
||||
|
||||
bool operator!=(const SamplerState& lhs, const SamplerState& rhs)
|
||||
{
|
||||
return !operator==(lhs, rhs);
|
||||
}
|
||||
|
||||
bool operator>(const SamplerState& lhs, const SamplerState& rhs)
|
||||
{
|
||||
return lhs.bits > rhs.bits;
|
||||
}
|
||||
|
||||
bool operator<(const SamplerState& lhs, const SamplerState& rhs)
|
||||
{
|
||||
return lhs.bits < rhs.bits;
|
||||
}
|
||||
|
||||
std::size_t ComputePipelineInfoHash::operator()(const ComputePipelineInfo& key) const
|
||||
{
|
||||
return static_cast<std::size_t>(XXH64(&key, sizeof(key), 0));
|
||||
@ -1214,7 +1182,8 @@ void ShaderCache::CreateDummyPipeline(const UberShader::VertexShaderUid& vuid,
|
||||
pinfo.depth_state.hex = RenderState::GetNoDepthTestingDepthStencilState().hex;
|
||||
pinfo.blend_state.hex = RenderState::GetNoBlendingBlendState().hex;
|
||||
pinfo.multisampling_state.hex = FramebufferManager::GetInstance()->GetEFBMultisamplingState().hex;
|
||||
pinfo.rasterization_state.primitive = guid.GetUidData()->primitive_type;
|
||||
pinfo.rasterization_state.primitive =
|
||||
static_cast<PrimitiveType>(guid.GetUidData()->primitive_type);
|
||||
GetPipelineWithCacheResultAsync(pinfo);
|
||||
}
|
||||
|
||||
|
@ -62,10 +62,6 @@ bool operator==(const PipelineInfo& lhs, const PipelineInfo& rhs);
|
||||
bool operator!=(const PipelineInfo& lhs, const PipelineInfo& rhs);
|
||||
bool operator<(const PipelineInfo& lhs, const PipelineInfo& rhs);
|
||||
bool operator>(const PipelineInfo& lhs, const PipelineInfo& rhs);
|
||||
bool operator==(const SamplerState& lhs, const SamplerState& rhs);
|
||||
bool operator!=(const SamplerState& lhs, const SamplerState& rhs);
|
||||
bool operator>(const SamplerState& lhs, const SamplerState& rhs);
|
||||
bool operator<(const SamplerState& lhs, const SamplerState& rhs);
|
||||
|
||||
struct ComputePipelineInfo
|
||||
{
|
||||
|
Reference in New Issue
Block a user