rsx: Make use of remapped border colors

This commit is contained in:
kd-11 2024-10-03 04:22:44 +03:00 committed by kd-11
parent d1d04b1b32
commit 497b9ba55b
7 changed files with 70 additions and 20 deletions

View File

@ -1572,4 +1572,25 @@ namespace rsx
return true;
}
}
bool is_border_clamped_texture(
rsx::texture_wrap_mode wrap_s,
rsx::texture_wrap_mode wrap_t,
rsx::texture_wrap_mode wrap_r,
rsx::texture_dimension dimension)
{
// Technically we should check border and mirror_once_border
// However, the latter is not implemented in any modern API, so we can just ignore it (emulated with mirror_once_clamp).
switch (dimension)
{
case rsx::texture_dimension::dimension1d:
return wrap_s == rsx::texture_wrap_mode::border;
case rsx::texture_dimension::dimension2d:
return wrap_s == rsx::texture_wrap_mode::border || wrap_t == rsx::texture_wrap_mode::border;
case rsx::texture_dimension::dimension3d:
return wrap_s == rsx::texture_wrap_mode::border || wrap_t == rsx::texture_wrap_mode::border || wrap_r == rsx::texture_wrap_mode::border;
default:
return false;
}
}
}

View File

@ -289,4 +289,11 @@ namespace rsx
format_class classify_format(u32 gcm_format);
bool is_texcoord_wrapping_mode(rsx::texture_wrap_mode mode);
bool is_border_clamped_texture(rsx::texture_wrap_mode wrap_s, rsx::texture_wrap_mode wrap_t, rsx::texture_wrap_mode wrap_r, rsx::texture_dimension dimension);
template <typename TextureType>
bool is_border_clamped_texture(const TextureType& tex)
{
return is_border_clamped_texture(tex.wrap_s(), tex.wrap_t(), tex.wrap_r(), tex.dimension());
}
}

View File

@ -79,14 +79,16 @@ namespace gl
set_parameteri(GL_TEXTURE_WRAP_T, wrap_mode(tex.wrap_t()));
set_parameteri(GL_TEXTURE_WRAP_R, wrap_mode(tex.wrap_r()));
if (const auto color = tex.border_color();
get_parameteri(GL_TEXTURE_BORDER_COLOR) != color)
if (rsx::is_border_clamped_texture(tex))
{
m_propertiesi[GL_TEXTURE_BORDER_COLOR] = color;
const color4f border_color = rsx::decode_border_color(color);
const auto border_color = tex.remapped_border_color();
const auto encoded_color = rsx::encode_color_to_storage_key(border_color);
if (get_parameteri(GL_TEXTURE_BORDER_COLOR) != encoded_color)
{
m_propertiesi[GL_TEXTURE_BORDER_COLOR] = encoded_color;
glSamplerParameterfv(sampler_handle, GL_TEXTURE_BORDER_COLOR, border_color.rgba);
}
}
if (sampled_image->upload_context != rsx::texture_upload_context::shader_read ||
tex.get_exact_mipmap_count() == 1)
@ -150,14 +152,16 @@ namespace gl
void sampler_state::apply(const rsx::vertex_texture& tex, const rsx::sampled_image_descriptor_base* /*sampled_image*/)
{
if (const auto color = tex.border_color();
get_parameteri(GL_TEXTURE_BORDER_COLOR) != color)
if (rsx::is_border_clamped_texture(tex))
{
m_propertiesi[GL_TEXTURE_BORDER_COLOR] = color;
const color4f border_color = rsx::decode_border_color(color);
const auto border_color = tex.remapped_border_color();
const auto encoded_color = rsx::encode_color_to_storage_key(border_color);
if (get_parameteri(GL_TEXTURE_BORDER_COLOR) != encoded_color)
{
m_propertiesi[GL_TEXTURE_BORDER_COLOR] = encoded_color;
glSamplerParameterfv(sampler_handle, GL_TEXTURE_BORDER_COLOR, border_color.rgba);
}
}
set_parameteri(GL_TEXTURE_WRAP_S, wrap_mode(tex.wrap_s()));
set_parameteri(GL_TEXTURE_WRAP_T, wrap_mode(tex.wrap_t()));

View File

@ -303,7 +303,9 @@ void VKGSRender::load_texture_env()
const auto wrap_s = vk::vk_wrap_mode(tex.wrap_s());
const auto wrap_t = vk::vk_wrap_mode(tex.wrap_t());
const auto wrap_r = vk::vk_wrap_mode(tex.wrap_r());
const auto border_color = vk::border_color_t(tex.border_color());
const auto border_color = rsx::is_border_clamped_texture(tex)
? vk::border_color_t(tex.remapped_border_color())
: vk::border_color_t(VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK);
// Check if non-point filtering can even be used on this format
bool can_sample_linear;
@ -441,11 +443,16 @@ void VKGSRender::load_texture_env()
const VkBool32 unnormalized_coords = !!(tex.format() & CELL_GCM_TEXTURE_UN);
const auto min_lod = tex.min_lod();
const auto max_lod = tex.max_lod();
const auto border_color = vk::border_color_t(tex.border_color());
const auto wrap_s = vk::vk_wrap_mode(tex.wrap_s());
const auto wrap_t = vk::vk_wrap_mode(tex.wrap_t());
const auto border_color = is_border_clamped_texture(tex)
? vk::border_color_t(tex.remapped_border_color())
: vk::border_color_t(VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK);
if (vs_sampler_handles[i])
{
if (!vs_sampler_handles[i]->matches(VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_REPEAT, 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))
{
replace = true;
@ -457,7 +464,7 @@ void VKGSRender::load_texture_env()
vs_sampler_handles[i] = vk::get_resource_manager()->get_sampler(
*m_device,
vs_sampler_handles[i],
VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_REPEAT,
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);

View File

@ -1,5 +1,6 @@
#include "memory.h"
#include "sampler.h"
#include "../../color_utils.h"
#include "../../rsx_utils.h"
namespace vk
@ -20,9 +21,10 @@ namespace vk
return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
}
border_color_t::border_color_t(u32 encoded_color, VkFormat fmt, VkImageAspectFlags aspect)
: storage_key(0), format(fmt), aspect(aspect)
border_color_t::border_color_t(const color4f& color, VkFormat fmt, VkImageAspectFlags aspect)
: format(fmt), aspect(aspect), color_value(color)
{
const auto encoded_color = rsx::encode_color_to_storage_key(color);
value = vk::get_border_color(encoded_color);
if (value != VK_BORDER_COLOR_FLOAT_CUSTOM_EXT)
@ -31,7 +33,6 @@ namespace vk
return;
}
color_value = rsx::decode_border_color(encoded_color);
if (!g_render_device->get_custom_border_color_support())
{
value = get_closest_border_color_enum(color_value);

View File

@ -13,7 +13,7 @@ namespace vk
VkImageCreateFlags aspect;
color4f color_value;
border_color_t(u32 encoded_color, VkFormat fmt = VK_FORMAT_UNDEFINED, VkImageAspectFlags aspect = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT);
border_color_t(const color4f& color, VkFormat fmt = VK_FORMAT_UNDEFINED, VkImageAspectFlags aspect = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT);
border_color_t(VkBorderColor color);

View File

@ -201,6 +201,16 @@ namespace rsx
return result;
}
static inline u32 encode_color_to_storage_key(color4f color)
{
const u32 r = static_cast<u8>(color.r * 255);
const u32 g = static_cast<u8>(color.g * 255);
const u32 b = static_cast<u8>(color.b * 255);
const u32 a = static_cast<u8>(color.a * 255);
return (a << 24) | (b << 16) | (g << 8) | r;
}
static inline const std::array<bool, 4> get_write_output_mask(rsx::surface_color_format format)
{
constexpr std::array<bool, 4> rgba = { true, true, true, true };