vk: De-sphaggetify texture handling
This commit is contained in:
+68
-47
@@ -263,7 +263,7 @@ void VKGSRender::load_texture_env()
|
|||||||
{
|
{
|
||||||
// Load textures
|
// Load textures
|
||||||
bool check_for_cyclic_refs = false;
|
bool check_for_cyclic_refs = false;
|
||||||
auto check_surface_cache_sampler = [&](auto descriptor, const auto& tex)
|
auto check_surface_cache_sampler_valid = [&](auto descriptor, const auto& tex)
|
||||||
{
|
{
|
||||||
if (!m_texture_cache.test_if_descriptor_expired(*m_current_command_buffer, m_rtts, descriptor, tex))
|
if (!m_texture_cache.test_if_descriptor_expired(*m_current_command_buffer, m_rtts, descriptor, tex))
|
||||||
{
|
{
|
||||||
@@ -286,28 +286,41 @@ void VKGSRender::load_texture_env()
|
|||||||
for (u32 textures_ref = current_fp_metadata.referenced_textures_mask, i = 0; textures_ref; textures_ref >>= 1, ++i)
|
for (u32 textures_ref = current_fp_metadata.referenced_textures_mask, i = 0; textures_ref; textures_ref >>= 1, ++i)
|
||||||
{
|
{
|
||||||
if (!(textures_ref & 1))
|
if (!(textures_ref & 1))
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!fs_sampler_state[i])
|
if (!fs_sampler_state[i])
|
||||||
|
{
|
||||||
fs_sampler_state[i] = std::make_unique<vk::texture_cache::sampled_image_descriptor>();
|
fs_sampler_state[i] = std::make_unique<vk::texture_cache::sampled_image_descriptor>();
|
||||||
|
}
|
||||||
|
|
||||||
auto sampler_state = static_cast<vk::texture_cache::sampled_image_descriptor*>(fs_sampler_state[i].get());
|
auto sampler_state = static_cast<vk::texture_cache::sampled_image_descriptor*>(fs_sampler_state[i].get());
|
||||||
const auto& tex = rsx::method_registers.fragment_textures[i];
|
const auto& tex = rsx::method_registers.fragment_textures[i];
|
||||||
const auto previous_format_class = fs_sampler_state[i]->format_class;
|
const auto previous_format_class = fs_sampler_state[i]->format_class;
|
||||||
|
|
||||||
if (m_samplers_dirty || m_textures_dirty[i] || !check_surface_cache_sampler(sampler_state, tex))
|
if (!m_samplers_dirty &&
|
||||||
|
!m_textures_dirty[i] &&
|
||||||
|
check_surface_cache_sampler_valid(sampler_state, tex))
|
||||||
{
|
{
|
||||||
if (tex.enabled())
|
continue;
|
||||||
{
|
|
||||||
*sampler_state = m_texture_cache.upload_texture(*m_current_command_buffer, tex, m_rtts);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*sampler_state = {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sampler_state->validate())
|
const bool is_sampler_dirty = m_textures_dirty[i];
|
||||||
|
m_textures_dirty[i] = false;
|
||||||
|
|
||||||
|
if (!tex.enabled())
|
||||||
{
|
{
|
||||||
|
*sampler_state = {};
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
*sampler_state = m_texture_cache.upload_texture(*m_current_command_buffer, tex, m_rtts);
|
||||||
|
if (!sampler_state->validate())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
sampler_state->format_ex = tex.format_ex();
|
sampler_state->format_ex = tex.format_ex();
|
||||||
|
|
||||||
if (sampler_state->is_cyclic_reference)
|
if (sampler_state->is_cyclic_reference)
|
||||||
@@ -315,13 +328,18 @@ void VKGSRender::load_texture_env()
|
|||||||
check_for_cyclic_refs |= true;
|
check_for_cyclic_refs |= true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_textures_dirty[i] && sampler_state->format_class != previous_format_class)
|
if (!is_sampler_dirty && sampler_state->format_class != previous_format_class)
|
||||||
{
|
{
|
||||||
// Host details changed but RSX is not aware
|
// Host details changed but RSX is not aware
|
||||||
m_graphics_state |= rsx::fragment_program_state_dirty;
|
m_graphics_state |= rsx::fragment_program_state_dirty;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool replace = !fs_sampler_handles[i];
|
if (!is_sampler_dirty && fs_sampler_handles[i])
|
||||||
|
{
|
||||||
|
// Nothing to change, use cached sampler
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
VkFilter mag_filter;
|
VkFilter mag_filter;
|
||||||
vk::minification_filter min_filter;
|
vk::minification_filter min_filter;
|
||||||
f32 min_lod = 0.f, max_lod = 0.f;
|
f32 min_lod = 0.f, max_lod = 0.f;
|
||||||
@@ -424,17 +442,13 @@ void VKGSRender::load_texture_env()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fs_sampler_handles[i] && m_textures_dirty[i])
|
if (fs_sampler_handles[i] &&
|
||||||
{
|
fs_sampler_handles[i]->matches(wrap_s, wrap_t, wrap_r, false, lod_bias, af_level, min_lod, max_lod,
|
||||||
if (!fs_sampler_handles[i]->matches(wrap_s, wrap_t, wrap_r, false, lod_bias, af_level, min_lod, max_lod,
|
|
||||||
min_filter.filter, mag_filter, min_filter.mipmap_mode, border_color, compare_enabled, depth_compare_mode))
|
min_filter.filter, mag_filter, min_filter.mipmap_mode, border_color, compare_enabled, depth_compare_mode))
|
||||||
{
|
{
|
||||||
replace = true;
|
continue;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (replace)
|
|
||||||
{
|
|
||||||
fs_sampler_handles[i] = vk::get_resource_manager()->get_sampler(
|
fs_sampler_handles[i] = vk::get_resource_manager()->get_sampler(
|
||||||
*m_device,
|
*m_device,
|
||||||
fs_sampler_handles[i],
|
fs_sampler_handles[i],
|
||||||
@@ -444,49 +458,61 @@ void VKGSRender::load_texture_env()
|
|||||||
min_filter.filter, mag_filter, min_filter.mipmap_mode,
|
min_filter.filter, mag_filter, min_filter.mipmap_mode,
|
||||||
border_color, compare_enabled, depth_compare_mode);
|
border_color, compare_enabled, depth_compare_mode);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
m_textures_dirty[i] = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (u32 textures_ref = current_vp_metadata.referenced_textures_mask, i = 0; textures_ref; textures_ref >>= 1, ++i)
|
for (u32 textures_ref = current_vp_metadata.referenced_textures_mask, i = 0; textures_ref; textures_ref >>= 1, ++i)
|
||||||
{
|
{
|
||||||
if (!(textures_ref & 1))
|
if (!(textures_ref & 1))
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!vs_sampler_state[i])
|
if (!vs_sampler_state[i])
|
||||||
|
{
|
||||||
vs_sampler_state[i] = std::make_unique<vk::texture_cache::sampled_image_descriptor>();
|
vs_sampler_state[i] = std::make_unique<vk::texture_cache::sampled_image_descriptor>();
|
||||||
|
}
|
||||||
|
|
||||||
auto sampler_state = static_cast<vk::texture_cache::sampled_image_descriptor*>(vs_sampler_state[i].get());
|
auto sampler_state = static_cast<vk::texture_cache::sampled_image_descriptor*>(vs_sampler_state[i].get());
|
||||||
const auto& tex = rsx::method_registers.vertex_textures[i];
|
const auto& tex = rsx::method_registers.vertex_textures[i];
|
||||||
const auto previous_format_class = sampler_state->format_class;
|
const auto previous_format_class = sampler_state->format_class;
|
||||||
|
|
||||||
if (m_samplers_dirty || m_vertex_textures_dirty[i] || !check_surface_cache_sampler(sampler_state, tex))
|
if (!m_samplers_dirty &&
|
||||||
|
!m_vertex_textures_dirty[i] &&
|
||||||
|
check_surface_cache_sampler_valid(sampler_state, tex))
|
||||||
{
|
{
|
||||||
if (rsx::method_registers.vertex_textures[i].enabled())
|
continue;
|
||||||
{
|
|
||||||
*sampler_state = m_texture_cache.upload_texture(*m_current_command_buffer, tex, m_rtts);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*sampler_state = {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sampler_state->validate())
|
const bool is_sampler_dirty = m_vertex_textures_dirty[i];
|
||||||
|
m_vertex_textures_dirty[i] = false;
|
||||||
|
|
||||||
|
if (!rsx::method_registers.vertex_textures[i].enabled())
|
||||||
{
|
{
|
||||||
|
*sampler_state = {};
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
*sampler_state = m_texture_cache.upload_texture(*m_current_command_buffer, tex, m_rtts);
|
||||||
|
if (!sampler_state->validate())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (sampler_state->is_cyclic_reference || sampler_state->external_subresource_desc.do_not_cache)
|
if (sampler_state->is_cyclic_reference || sampler_state->external_subresource_desc.do_not_cache)
|
||||||
{
|
{
|
||||||
check_for_cyclic_refs |= true;
|
check_for_cyclic_refs |= true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_vertex_textures_dirty[i] && sampler_state->format_class != previous_format_class)
|
if (!is_sampler_dirty && sampler_state->format_class != previous_format_class)
|
||||||
{
|
{
|
||||||
// Host details changed but RSX is not aware
|
// Host details changed but RSX is not aware
|
||||||
m_graphics_state |= rsx::vertex_program_state_dirty;
|
m_graphics_state |= rsx::vertex_program_state_dirty;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool replace = !vs_sampler_handles[i];
|
if (!is_sampler_dirty && vs_sampler_handles[i])
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const VkBool32 unnormalized_coords = !!(tex.format() & CELL_GCM_TEXTURE_UN);
|
const VkBool32 unnormalized_coords = !!(tex.format() & CELL_GCM_TEXTURE_UN);
|
||||||
const auto min_lod = tex.min_lod();
|
const auto min_lod = tex.min_lod();
|
||||||
const auto max_lod = tex.max_lod();
|
const auto max_lod = tex.max_lod();
|
||||||
@@ -499,17 +525,13 @@ void VKGSRender::load_texture_env()
|
|||||||
? vk::border_color_t(get_border_color(tex))
|
? vk::border_color_t(get_border_color(tex))
|
||||||
: vk::border_color_t(VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK);
|
: vk::border_color_t(VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK);
|
||||||
|
|
||||||
if (vs_sampler_handles[i])
|
if (vs_sampler_handles[i] &&
|
||||||
{
|
vs_sampler_handles[i]->matches(wrap_s, wrap_t, VK_SAMPLER_ADDRESS_MODE_REPEAT,
|
||||||
if (!vs_sampler_handles[i]->matches(wrap_s, wrap_t, VK_SAMPLER_ADDRESS_MODE_REPEAT,
|
|
||||||
unnormalized_coords, 0.f, 1.f, min_lod, max_lod, VK_FILTER_NEAREST, VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST, border_color))
|
unnormalized_coords, 0.f, 1.f, min_lod, max_lod, VK_FILTER_NEAREST, VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST, border_color))
|
||||||
{
|
{
|
||||||
replace = true;
|
continue;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (replace)
|
|
||||||
{
|
|
||||||
vs_sampler_handles[i] = vk::get_resource_manager()->get_sampler(
|
vs_sampler_handles[i] = vk::get_resource_manager()->get_sampler(
|
||||||
*m_device,
|
*m_device,
|
||||||
vs_sampler_handles[i],
|
vs_sampler_handles[i],
|
||||||
@@ -518,11 +540,6 @@ void VKGSRender::load_texture_env()
|
|||||||
0.f, 1.f, min_lod, max_lod,
|
0.f, 1.f, min_lod, max_lod,
|
||||||
VK_FILTER_NEAREST, VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST, border_color);
|
VK_FILTER_NEAREST, VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST, border_color);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
m_vertex_textures_dirty[i] = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_samplers_dirty.store(false);
|
m_samplers_dirty.store(false);
|
||||||
|
|
||||||
@@ -557,7 +574,9 @@ bool VKGSRender::bind_texture_env()
|
|||||||
for (u32 textures_ref = current_fp_metadata.referenced_textures_mask, i = 0; textures_ref; textures_ref >>= 1, ++i)
|
for (u32 textures_ref = current_fp_metadata.referenced_textures_mask, i = 0; textures_ref; textures_ref >>= 1, ++i)
|
||||||
{
|
{
|
||||||
if (!(textures_ref & 1))
|
if (!(textures_ref & 1))
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
vk::image_view* view = nullptr;
|
vk::image_view* view = nullptr;
|
||||||
auto sampler_state = static_cast<vk::texture_cache::sampled_image_descriptor*>(fs_sampler_state[i].get());
|
auto sampler_state = static_cast<vk::texture_cache::sampled_image_descriptor*>(fs_sampler_state[i].get());
|
||||||
@@ -627,7 +646,9 @@ bool VKGSRender::bind_texture_env()
|
|||||||
for (u32 textures_ref = current_vp_metadata.referenced_textures_mask, i = 0; textures_ref; textures_ref >>= 1, ++i)
|
for (u32 textures_ref = current_vp_metadata.referenced_textures_mask, i = 0; textures_ref; textures_ref >>= 1, ++i)
|
||||||
{
|
{
|
||||||
if (!(textures_ref & 1))
|
if (!(textures_ref & 1))
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!rsx::method_registers.vertex_textures[i].enabled())
|
if (!rsx::method_registers.vertex_textures[i].enabled())
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user