rsx: Get rid of some guessing when handling special hardware formats
This commit is contained in:
@@ -135,6 +135,12 @@ namespace rsx
|
|||||||
RSX_FORMAT_FEATURE_16BIT_CHANNELS = (1 << 3), // Complements RSX_FORMAT_FEATURE_SIGNED_COMPONENTS
|
RSX_FORMAT_FEATURE_16BIT_CHANNELS = (1 << 3), // Complements RSX_FORMAT_FEATURE_SIGNED_COMPONENTS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum host_format_features : u8
|
||||||
|
{
|
||||||
|
RSX_HOST_FORMAT_FEATURE_SNORM = (1 << 0),
|
||||||
|
RSX_HOST_FORMAT_FEATURE_SRGB = (1 << 1),
|
||||||
|
};
|
||||||
|
|
||||||
using enum format_features;
|
using enum format_features;
|
||||||
|
|
||||||
struct texture_format_ex
|
struct texture_format_ex
|
||||||
@@ -150,10 +156,14 @@ namespace rsx
|
|||||||
bool hw_SNORM_possible() const;
|
bool hw_SNORM_possible() const;
|
||||||
bool hw_SRGB_possible() const;
|
bool hw_SRGB_possible() const;
|
||||||
|
|
||||||
|
bool host_snorm_format_active() const { return host_features & RSX_HOST_FORMAT_FEATURE_SNORM; }
|
||||||
|
bool host_srgb_format_active() const { return host_features & RSX_HOST_FORMAT_FEATURE_SRGB; }
|
||||||
|
|
||||||
//private:
|
//private:
|
||||||
u32 format_bits = 0;
|
u32 format_bits = 0;
|
||||||
u32 features = 0;
|
u32 features = 0;
|
||||||
u32 texel_remap_control = 0;
|
u32 texel_remap_control = 0;
|
||||||
|
u32 host_features = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Sampled image descriptor
|
// Sampled image descriptor
|
||||||
|
|||||||
@@ -361,22 +361,26 @@ void GLGSRender::load_texture_env()
|
|||||||
const auto gl_format = sampler_state->image_handle->view_format();
|
const auto gl_format = sampler_state->image_handle->view_format();
|
||||||
GLenum format_override = gl_format;
|
GLenum format_override = gl_format;
|
||||||
rsx::flags32_t flags_to_erase = 0u;
|
rsx::flags32_t flags_to_erase = 0u;
|
||||||
|
rsx::flags32_t host_flags_to_set = 0u;
|
||||||
|
|
||||||
if (sampler_state->format_ex.hw_SNORM_possible())
|
if (sampler_state->format_ex.hw_SNORM_possible())
|
||||||
{
|
{
|
||||||
format_override = gl::get_compatible_snorm_format(gl_format);
|
format_override = gl::get_compatible_snorm_format(gl_format);
|
||||||
flags_to_erase = rsx::texture_control_bits::SEXT_MASK;
|
flags_to_erase = rsx::texture_control_bits::SEXT_MASK;
|
||||||
|
host_flags_to_set = rsx::RSX_HOST_FORMAT_FEATURE_SNORM;
|
||||||
}
|
}
|
||||||
else if (sampler_state->format_ex.hw_SRGB_possible())
|
else if (sampler_state->format_ex.hw_SRGB_possible())
|
||||||
{
|
{
|
||||||
format_override = gl::get_compatible_srgb_format(gl_format);
|
format_override = gl::get_compatible_srgb_format(gl_format);
|
||||||
flags_to_erase = rsx::texture_control_bits::GAMMA_CTRL_MASK;
|
flags_to_erase = rsx::texture_control_bits::GAMMA_CTRL_MASK;
|
||||||
|
host_flags_to_set = rsx::RSX_HOST_FORMAT_FEATURE_SRGB;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (format_override != GL_NONE && format_override != gl_format)
|
if (format_override != GL_NONE && format_override != gl_format)
|
||||||
{
|
{
|
||||||
sampler_state->image_handle = sampler_state->image_handle->as(format_override);
|
sampler_state->image_handle = sampler_state->image_handle->as(format_override);
|
||||||
sampler_state->format_ex.texel_remap_control &= (~flags_to_erase);
|
sampler_state->format_ex.texel_remap_control &= (~flags_to_erase);
|
||||||
|
sampler_state->format_ex.host_features |= host_flags_to_set;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -84,23 +84,25 @@ namespace gl
|
|||||||
// Therefore, we pass the raw value here, and the texture view will handle the rest for us.
|
// Therefore, we pass the raw value here, and the texture view will handle the rest for us.
|
||||||
const bool sext_conv_required = (sampled_image->format_ex.texel_remap_control & rsx::SEXT_MASK) != 0;
|
const bool sext_conv_required = (sampled_image->format_ex.texel_remap_control & rsx::SEXT_MASK) != 0;
|
||||||
const auto encoded_color = tex.border_color(sext_conv_required);
|
const auto encoded_color = tex.border_color(sext_conv_required);
|
||||||
if (get_parameteri(GL_TEXTURE_BORDER_COLOR) != encoded_color)
|
const auto host_features = sampled_image->format_ex.host_features;
|
||||||
|
|
||||||
|
if (get_parameteri(GL_TEXTURE_BORDER_COLOR) != encoded_color ||
|
||||||
|
get_parameteri(GL_TEXTURE_BORDER_VALUES_NV) != host_features)
|
||||||
{
|
{
|
||||||
m_propertiesi[GL_TEXTURE_BORDER_COLOR] = encoded_color;
|
m_propertiesi[GL_TEXTURE_BORDER_COLOR] = encoded_color;
|
||||||
auto border_color = rsx::decode_border_color(encoded_color);
|
m_propertiesi[GL_TEXTURE_BORDER_VALUES_NV] = host_features;
|
||||||
|
|
||||||
if (const auto snorm_mask = tex.argb_signed();
|
auto border_color = rsx::decode_border_color(encoded_color);
|
||||||
!sext_conv_required && tex.argb_signed()) [[ unlikely ]]
|
if (sampled_image->format_ex.host_snorm_format_active()) [[ unlikely ]]
|
||||||
{
|
{
|
||||||
// Hardware SNORM is active
|
// Hardware SNORM is active
|
||||||
ensure(sampled_image->format_ex.hw_SNORM_possible());
|
|
||||||
|
|
||||||
// Convert the border color in host space (2N - 1)
|
// Convert the border color in host space (2N - 1)
|
||||||
// HW does the conversion in integer space as (x - 128) / 127 which introduces a biasing error.
|
// HW does the conversion in integer space as (x - 128) / 127 which introduces a biasing error.
|
||||||
const float bias_v = 128.f / 255.f;
|
const float bias_v = 128.f / 255.f;
|
||||||
const float scale_v = 255.f / 127.f;
|
const float scale_v = 255.f / 127.f;
|
||||||
|
|
||||||
color4f scale{ 1.f }, bias{ 0.f };
|
color4f scale{ 1.f }, bias{ 0.f };
|
||||||
|
const auto snorm_mask = tex.argb_signed();
|
||||||
if (snorm_mask & 1) { scale.a = scale_v; bias.a = -bias_v; }
|
if (snorm_mask & 1) { scale.a = scale_v; bias.a = -bias_v; }
|
||||||
if (snorm_mask & 2) { scale.r = scale_v; bias.r = -bias_v; }
|
if (snorm_mask & 2) { scale.r = scale_v; bias.r = -bias_v; }
|
||||||
if (snorm_mask & 4) { scale.g = scale_v; bias.g = -bias_v; }
|
if (snorm_mask & 4) { scale.g = scale_v; bias.g = -bias_v; }
|
||||||
|
|||||||
@@ -353,22 +353,26 @@ void VKGSRender::load_texture_env()
|
|||||||
const auto vk_format = sampler_state->image_handle->format();
|
const auto vk_format = sampler_state->image_handle->format();
|
||||||
VkFormat format_override = vk_format;;
|
VkFormat format_override = vk_format;;
|
||||||
rsx::flags32_t flags_to_erase = 0u;
|
rsx::flags32_t flags_to_erase = 0u;
|
||||||
|
rsx::flags32_t host_flags_to_set = 0u;
|
||||||
|
|
||||||
if (sampler_state->format_ex.hw_SNORM_possible())
|
if (sampler_state->format_ex.hw_SNORM_possible())
|
||||||
{
|
{
|
||||||
format_override = vk::get_compatible_snorm_format(vk_format);
|
format_override = vk::get_compatible_snorm_format(vk_format);
|
||||||
flags_to_erase = rsx::texture_control_bits::SEXT_MASK;
|
flags_to_erase = rsx::texture_control_bits::SEXT_MASK;
|
||||||
|
host_flags_to_set = rsx::RSX_HOST_FORMAT_FEATURE_SNORM;
|
||||||
}
|
}
|
||||||
else if (sampler_state->format_ex.hw_SRGB_possible())
|
else if (sampler_state->format_ex.hw_SRGB_possible())
|
||||||
{
|
{
|
||||||
format_override = vk::get_compatible_srgb_format(vk_format);
|
format_override = vk::get_compatible_srgb_format(vk_format);
|
||||||
flags_to_erase = rsx::texture_control_bits::GAMMA_CTRL_MASK;
|
flags_to_erase = rsx::texture_control_bits::GAMMA_CTRL_MASK;
|
||||||
|
host_flags_to_set = rsx::RSX_HOST_FORMAT_FEATURE_SRGB;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (format_override != VK_FORMAT_UNDEFINED && format_override != vk_format)
|
if (format_override != VK_FORMAT_UNDEFINED && format_override != vk_format)
|
||||||
{
|
{
|
||||||
sampler_state->image_handle = sampler_state->image_handle->as(format_override);
|
sampler_state->image_handle = sampler_state->image_handle->as(format_override);
|
||||||
sampler_state->format_ex.texel_remap_control &= (~flags_to_erase);
|
sampler_state->format_ex.texel_remap_control &= (~flags_to_erase);
|
||||||
|
sampler_state->format_ex.host_features |= host_flags_to_set;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -400,8 +404,7 @@ void VKGSRender::load_texture_env()
|
|||||||
if (rsx::is_border_clamped_texture(tex))
|
if (rsx::is_border_clamped_texture(tex))
|
||||||
{
|
{
|
||||||
auto color_value = get_border_color(tex, sext_conv_required);
|
auto color_value = get_border_color(tex, sext_conv_required);
|
||||||
if (const auto snorm_mask = tex.argb_signed();
|
if (sampler_state->format_ex.host_snorm_format_active())
|
||||||
!sext_conv_required && snorm_mask)
|
|
||||||
{
|
{
|
||||||
// Convert the border color in host space (2N - 1)
|
// Convert the border color in host space (2N - 1)
|
||||||
// HW does the conversion in integer space as (x - 128) / 127 which introduces a biasing error.
|
// HW does the conversion in integer space as (x - 128) / 127 which introduces a biasing error.
|
||||||
@@ -409,6 +412,7 @@ void VKGSRender::load_texture_env()
|
|||||||
const float scale_v = 255.f / 127.f;
|
const float scale_v = 255.f / 127.f;
|
||||||
|
|
||||||
color4f scale{ 1.f }, bias{ 0.f };
|
color4f scale{ 1.f }, bias{ 0.f };
|
||||||
|
const auto snorm_mask = tex.argb_signed();
|
||||||
if (snorm_mask & 1) { scale.a = scale_v; bias.a = -bias_v; }
|
if (snorm_mask & 1) { scale.a = scale_v; bias.a = -bias_v; }
|
||||||
if (snorm_mask & 2) { scale.r = scale_v; bias.r = -bias_v; }
|
if (snorm_mask & 2) { scale.r = scale_v; bias.r = -bias_v; }
|
||||||
if (snorm_mask & 4) { scale.g = scale_v; bias.g = -bias_v; }
|
if (snorm_mask & 4) { scale.g = scale_v; bias.g = -bias_v; }
|
||||||
|
|||||||
Reference in New Issue
Block a user