mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-08-19 14:36:15 +00:00
[TEST] Adjustments over the vkformat undefined and border color swizzle
This commit is contained in:
@@ -370,7 +370,7 @@ inline void PushImageDescriptors(TextureCache& texture_cache,
|
||||
const VkImageView null_image_view{texture_cache.GetImageView(VideoCommon::NULL_IMAGE_VIEW_ID).Handle(desc.type)};
|
||||
if (null_image_view != VK_NULL_HANDLE) vk_image_view = null_image_view;
|
||||
}
|
||||
const Sampler& sampler{texture_cache.GetSampler(sampler_id)};
|
||||
Sampler& sampler{texture_cache.GetSampler(sampler_id)};
|
||||
const bool use_fallback_sampler{sampler.HasAddedAnisotropy() &&
|
||||
!image_view.SupportsAnisotropy()};
|
||||
VkSampler vk_sampler{use_fallback_sampler ? sampler.HandleWithDefaultAnisotropy()
|
||||
@@ -383,8 +383,11 @@ inline void PushImageDescriptors(TextureCache& texture_cache,
|
||||
!image_view.SupportsDepthComparison()) {
|
||||
vk_sampler = sampler.HandleWithoutDepthComparison();
|
||||
}
|
||||
if (sampler.HasSrgbBorderColor() &&
|
||||
VideoCore::Surface::IsPixelFormatSRGB(image_view.format)) {
|
||||
const bool srgb_border{sampler.HasSrgbBorderColor() &&
|
||||
VideoCore::Surface::IsPixelFormatSRGB(image_view.format)};
|
||||
if (sampler.NeedsSwizzleMapping() && !image_view.HasIdentitySwizzle()) {
|
||||
vk_sampler = sampler.HandleWithSwizzle(image_view.Swizzle(), srgb_border);
|
||||
} else if (srgb_border) {
|
||||
vk_sampler = sampler.HandleWithSrgbBorderColor();
|
||||
}
|
||||
if (sampler.HasMinmaxReduction() && !image_view.SupportsMinmaxFilter()) {
|
||||
|
||||
@@ -2405,6 +2405,14 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI
|
||||
VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT) != 0;
|
||||
}
|
||||
requires_border_color_format = NeedsExplicitBorderColorFormat(format_info.format);
|
||||
swizzle_mapping = VkComponentMapping{
|
||||
.r = ComponentSwizzle(swizzle[0]),
|
||||
.g = ComponentSwizzle(swizzle[1]),
|
||||
.b = ComponentSwizzle(swizzle[2]),
|
||||
.a = ComponentSwizzle(swizzle[3]),
|
||||
};
|
||||
has_identity_swizzle = swizzle[0] == SwizzleSource::R && swizzle[1] == SwizzleSource::G &&
|
||||
swizzle[2] == SwizzleSource::B && swizzle[3] == SwizzleSource::A;
|
||||
const VkImageUsageFlags requested_view_usage = ImageUsageFlags(format_info, format);
|
||||
const VkImageUsageFlags image_usage = image.UsageFlags();
|
||||
const VkImageUsageFlags clamped_view_usage = requested_view_usage & image_usage;
|
||||
@@ -2429,12 +2437,7 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI
|
||||
.image = image.Handle(),
|
||||
.viewType = VkImageViewType{},
|
||||
.format = format_info.format,
|
||||
.components{
|
||||
.r = ComponentSwizzle(swizzle[0]),
|
||||
.g = ComponentSwizzle(swizzle[1]),
|
||||
.b = ComponentSwizzle(swizzle[2]),
|
||||
.a = ComponentSwizzle(swizzle[3]),
|
||||
},
|
||||
.components = swizzle_mapping,
|
||||
.subresourceRange = MakeSubresourceRange(aspect_mask, info.range),
|
||||
};
|
||||
const auto create = [&](TextureType tex_type, std::optional<u32> num_layers) {
|
||||
@@ -2671,6 +2674,33 @@ Sampler::Sampler(TextureCacheRuntime& runtime, const Tegra::Texture::TSCEntry& t
|
||||
min_filter == VK_FILTER_LINEAR ||
|
||||
mipmap_mode == VK_SAMPLER_MIPMAP_MODE_LINEAR};
|
||||
|
||||
const auto make_create_info = [&](const f32 anisotropy, bool force_nearest,
|
||||
bool disable_compare, const void* chain,
|
||||
VkBorderColor fixed_border) {
|
||||
return VkSamplerCreateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
|
||||
.pNext = chain,
|
||||
.flags = 0,
|
||||
.magFilter = force_nearest ? VK_FILTER_NEAREST : mag_filter,
|
||||
.minFilter = force_nearest ? VK_FILTER_NEAREST : min_filter,
|
||||
.mipmapMode = force_nearest ? VK_SAMPLER_MIPMAP_MODE_NEAREST : mipmap_mode,
|
||||
.addressModeU = MaxwellToVK::Sampler::WrapMode(device, tsc.wrap_u, tsc.mag_filter),
|
||||
.addressModeV = MaxwellToVK::Sampler::WrapMode(device, tsc.wrap_v, tsc.mag_filter),
|
||||
.addressModeW = MaxwellToVK::Sampler::WrapMode(device, tsc.wrap_p, tsc.mag_filter),
|
||||
.mipLodBias = tsc.LodBias(),
|
||||
.anisotropyEnable =
|
||||
static_cast<VkBool32>(!force_nearest && anisotropy > 1.0f ? VK_TRUE : VK_FALSE),
|
||||
.maxAnisotropy = force_nearest ? 1.0f : anisotropy,
|
||||
.compareEnable = disable_compare ? VK_FALSE
|
||||
: static_cast<VkBool32>(tsc.depth_compare_enabled),
|
||||
.compareOp = MaxwellToVK::Sampler::DepthCompareFunction(tsc.depth_compare_func),
|
||||
.minLod = tsc.mipmap_filter == TextureMipmapFilter::None ? 0.0f : tsc.MinLod(),
|
||||
.maxLod = tsc.mipmap_filter == TextureMipmapFilter::None ? 0.25f : tsc.MaxLod(),
|
||||
.borderColor = fixed_border,
|
||||
.unnormalizedCoordinates = VK_FALSE,
|
||||
};
|
||||
};
|
||||
|
||||
const auto create_sampler = [&](const f32 anisotropy, bool force_nearest,
|
||||
bool disable_compare = false,
|
||||
bool disable_custom_border = false,
|
||||
@@ -2698,28 +2728,8 @@ Sampler::Sampler(TextureCacheRuntime& runtime, const Tegra::Texture::TSCEntry& t
|
||||
fixed_border = ConvertBorderColor(srgb_color);
|
||||
}
|
||||
}
|
||||
return device.GetLogical().CreateSampler(VkSamplerCreateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
|
||||
.pNext = chain,
|
||||
.flags = 0,
|
||||
.magFilter = force_nearest ? VK_FILTER_NEAREST : mag_filter,
|
||||
.minFilter = force_nearest ? VK_FILTER_NEAREST : min_filter,
|
||||
.mipmapMode = force_nearest ? VK_SAMPLER_MIPMAP_MODE_NEAREST : mipmap_mode,
|
||||
.addressModeU = MaxwellToVK::Sampler::WrapMode(device, tsc.wrap_u, tsc.mag_filter),
|
||||
.addressModeV = MaxwellToVK::Sampler::WrapMode(device, tsc.wrap_v, tsc.mag_filter),
|
||||
.addressModeW = MaxwellToVK::Sampler::WrapMode(device, tsc.wrap_p, tsc.mag_filter),
|
||||
.mipLodBias = tsc.LodBias(),
|
||||
.anisotropyEnable =
|
||||
static_cast<VkBool32>(!force_nearest && anisotropy > 1.0f ? VK_TRUE : VK_FALSE),
|
||||
.maxAnisotropy = force_nearest ? 1.0f : anisotropy,
|
||||
.compareEnable = disable_compare ? VK_FALSE
|
||||
: static_cast<VkBool32>(tsc.depth_compare_enabled),
|
||||
.compareOp = MaxwellToVK::Sampler::DepthCompareFunction(tsc.depth_compare_func),
|
||||
.minLod = tsc.mipmap_filter == TextureMipmapFilter::None ? 0.0f : tsc.MinLod(),
|
||||
.maxLod = tsc.mipmap_filter == TextureMipmapFilter::None ? 0.25f : tsc.MaxLod(),
|
||||
.borderColor = fixed_border,
|
||||
.unnormalizedCoordinates = VK_FALSE,
|
||||
});
|
||||
return device.GetLogical().CreateSampler(
|
||||
make_create_info(anisotropy, force_nearest, disable_compare, chain, fixed_border));
|
||||
};
|
||||
|
||||
sampler = create_sampler(max_anisotropy, false);
|
||||
@@ -2744,6 +2754,60 @@ Sampler::Sampler(TextureCacheRuntime& runtime, const Tegra::Texture::TSCEntry& t
|
||||
sampler_srgb_border =
|
||||
create_sampler(max_anisotropy, false, false, false, false, true);
|
||||
}
|
||||
needs_swizzle_mapping = has_custom_border_colors && device.NeedsBorderColorSwizzleMapping();
|
||||
if (needs_swizzle_mapping) {
|
||||
device_ptr = &device;
|
||||
border_color_value = color;
|
||||
srgb_border_color_value = srgb_color;
|
||||
swizzle_reduction_mode = reduction_ci.reductionMode;
|
||||
swizzle_uses_reduction = has_minmax_reduction;
|
||||
swizzle_base_ci = make_create_info(max_anisotropy, false, false, nullptr,
|
||||
VK_BORDER_COLOR_FLOAT_CUSTOM_EXT);
|
||||
}
|
||||
}
|
||||
|
||||
VkSampler Sampler::HandleWithSwizzle(const VkComponentMapping& mapping, bool srgb) {
|
||||
const auto matches = [&](const SwizzleVariant& variant) {
|
||||
return variant.srgb == srgb && variant.mapping.r == mapping.r &&
|
||||
variant.mapping.g == mapping.g && variant.mapping.b == mapping.b &&
|
||||
variant.mapping.a == mapping.a;
|
||||
};
|
||||
const auto it = std::ranges::find_if(swizzle_variants, matches);
|
||||
if (it != swizzle_variants.end()) {
|
||||
return *it->sampler;
|
||||
}
|
||||
std::array<float, 4> value = border_color_value;
|
||||
if (srgb) {
|
||||
value = srgb_border_color_value;
|
||||
}
|
||||
const VkSamplerCustomBorderColorCreateInfoEXT border_ci{
|
||||
.sType = VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT,
|
||||
.pNext = nullptr,
|
||||
.customBorderColor = std::bit_cast<VkClearColorValue>(value),
|
||||
.format = VK_FORMAT_UNDEFINED,
|
||||
};
|
||||
const VkSamplerBorderColorComponentMappingCreateInfoEXT mapping_ci{
|
||||
.sType = VK_STRUCTURE_TYPE_SAMPLER_BORDER_COLOR_COMPONENT_MAPPING_CREATE_INFO_EXT,
|
||||
.pNext = &border_ci,
|
||||
.components = mapping,
|
||||
.srgb = VK_FALSE,
|
||||
};
|
||||
const VkSamplerReductionModeCreateInfoEXT reduction_ci{
|
||||
.sType = VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT,
|
||||
.pNext = &mapping_ci,
|
||||
.reductionMode = swizzle_reduction_mode,
|
||||
};
|
||||
VkSamplerCreateInfo create_info = swizzle_base_ci;
|
||||
create_info.pNext = &mapping_ci;
|
||||
if (swizzle_uses_reduction) {
|
||||
create_info.pNext = &reduction_ci;
|
||||
}
|
||||
swizzle_variants.push_back(SwizzleVariant{
|
||||
.mapping = mapping,
|
||||
.srgb = srgb,
|
||||
.sampler = device_ptr->GetLogical().CreateSampler(create_info),
|
||||
});
|
||||
return *swizzle_variants.back().sampler;
|
||||
}
|
||||
|
||||
Framebuffer::Framebuffer(TextureCacheRuntime& runtime, std::span<ImageView*, NUM_RT> color_buffers,
|
||||
|
||||
@@ -422,6 +422,14 @@ public:
|
||||
return supports_minmax_filter;
|
||||
}
|
||||
|
||||
[[nodiscard]] const VkComponentMapping& Swizzle() const noexcept {
|
||||
return swizzle_mapping;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool HasIdentitySwizzle() const noexcept {
|
||||
return has_identity_swizzle;
|
||||
}
|
||||
|
||||
[[nodiscard]] GPUVAddr GpuAddr() const noexcept {
|
||||
return gpu_addr;
|
||||
}
|
||||
@@ -454,9 +462,12 @@ private:
|
||||
VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
u32 buffer_size = 0;
|
||||
|
||||
VkComponentMapping swizzle_mapping{};
|
||||
|
||||
bool supports_depth_comparison = false;
|
||||
bool requires_border_color_format = false;
|
||||
bool supports_minmax_filter = false;
|
||||
bool has_identity_swizzle = true;
|
||||
};
|
||||
|
||||
class ImageAlloc : public VideoCommon::ImageAllocBase {};
|
||||
@@ -517,7 +528,19 @@ public:
|
||||
return static_cast<bool>(sampler_srgb_border);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool NeedsSwizzleMapping() const noexcept {
|
||||
return needs_swizzle_mapping;
|
||||
}
|
||||
|
||||
[[nodiscard]] VkSampler HandleWithSwizzle(const VkComponentMapping& mapping, bool srgb);
|
||||
|
||||
private:
|
||||
struct SwizzleVariant {
|
||||
VkComponentMapping mapping;
|
||||
bool srgb;
|
||||
vk::Sampler sampler;
|
||||
};
|
||||
|
||||
vk::Sampler sampler;
|
||||
vk::Sampler sampler_default_anisotropy;
|
||||
vk::Sampler sampler_nearest;
|
||||
@@ -525,6 +548,15 @@ private:
|
||||
vk::Sampler sampler_default_border;
|
||||
vk::Sampler sampler_default_reduction;
|
||||
vk::Sampler sampler_srgb_border;
|
||||
|
||||
std::vector<SwizzleVariant> swizzle_variants;
|
||||
const Device* device_ptr = nullptr;
|
||||
VkSamplerCreateInfo swizzle_base_ci{};
|
||||
VkSamplerReductionModeEXT swizzle_reduction_mode = VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT;
|
||||
std::array<float, 4> border_color_value{};
|
||||
std::array<float, 4> srgb_border_color_value{};
|
||||
bool swizzle_uses_reduction = false;
|
||||
bool needs_swizzle_mapping = false;
|
||||
};
|
||||
|
||||
struct TextureCacheParams {
|
||||
|
||||
@@ -1343,9 +1343,7 @@ void Device::RemoveUnsuitableExtensions() {
|
||||
// VK_EXT_border_color_swizzle
|
||||
if (extensions.border_color_swizzle) {
|
||||
extensions.border_color_swizzle =
|
||||
extensions.custom_border_color &&
|
||||
features.border_color_swizzle.borderColorSwizzle &&
|
||||
features.border_color_swizzle.borderColorSwizzleFromImage;
|
||||
extensions.custom_border_color && features.border_color_swizzle.borderColorSwizzle;
|
||||
}
|
||||
RemoveExtensionFeatureIfUnsuitable(extensions.border_color_swizzle,
|
||||
features.border_color_swizzle,
|
||||
|
||||
@@ -724,6 +724,12 @@ FN_MAX_LIMIT_LIST
|
||||
return extensions.border_color_swizzle;
|
||||
}
|
||||
|
||||
/// Returns true if samplers must be carried with border color swizzle mapping.
|
||||
bool NeedsBorderColorSwizzleMapping() const {
|
||||
return extensions.border_color_swizzle &&
|
||||
!features.border_color_swizzle.borderColorSwizzleFromImage;
|
||||
}
|
||||
|
||||
/// Returns true if borderColorSwizzleFromImage is available.
|
||||
bool IsBorderColorSwizzleFromImageSupported() const {
|
||||
return features.border_color_swizzle.borderColorSwizzleFromImage;
|
||||
|
||||
Reference in New Issue
Block a user