forked from etc/pineapple-src
early-access version 3682
This commit is contained in:
parent
22fb9ebe53
commit
915fe36508
22 changed files with 105 additions and 222 deletions
|
@ -1,7 +1,7 @@
|
|||
yuzu emulator early access
|
||||
=============
|
||||
|
||||
This is the source code for early-access 3680.
|
||||
This is the source code for early-access 3682.
|
||||
|
||||
## Legal Notice
|
||||
|
||||
|
|
|
@ -245,7 +245,6 @@ void RestoreGlobalState(bool is_powered_on) {
|
|||
values.bg_blue.SetGlobal(true);
|
||||
values.enable_compute_pipelines.SetGlobal(true);
|
||||
values.use_video_framerate.SetGlobal(true);
|
||||
values.use_aggressive_anisotropic_filtering.SetGlobal(true);
|
||||
|
||||
// System
|
||||
values.language_index.SetGlobal(true);
|
||||
|
|
|
@ -483,8 +483,7 @@ struct Values {
|
|||
AstcRecompression::Uncompressed, AstcRecompression::Uncompressed, AstcRecompression::Bc3,
|
||||
"astc_recompression"};
|
||||
SwitchableSetting<bool> use_video_framerate{false, "use_video_framerate"};
|
||||
SwitchableSetting<bool> use_aggressive_anisotropic_filtering{
|
||||
false, "use_aggressive_anisotropic_filtering"};
|
||||
SwitchableSetting<bool> barrier_feedback_loops{true, "barrier_feedback_loops"};
|
||||
|
||||
SwitchableSetting<u8> bg_red{0, "bg_red"};
|
||||
SwitchableSetting<u8> bg_green{0, "bg_green"};
|
||||
|
|
|
@ -275,9 +275,9 @@ GraphicsPipeline::GraphicsPipeline(const Device& device, TextureCache& texture_c
|
|||
template <typename Spec>
|
||||
void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
|
||||
std::array<VideoCommon::ImageViewInOut, MAX_TEXTURES + MAX_IMAGES> views;
|
||||
std::array<const Sampler*, MAX_TEXTURES> samplers;
|
||||
std::array<GLuint, MAX_TEXTURES> samplers;
|
||||
size_t views_index{};
|
||||
size_t samplers_index{};
|
||||
GLsizei sampler_binding{};
|
||||
|
||||
texture_cache.SynchronizeGraphicsDescriptors();
|
||||
|
||||
|
@ -337,6 +337,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
|
|||
for (u32 index = 0; index < desc.count; ++index) {
|
||||
const auto handle{read_handle(desc, index)};
|
||||
views[views_index++] = {handle.first};
|
||||
samplers[sampler_binding++] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -351,7 +352,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
|
|||
views[views_index++] = {handle.first};
|
||||
|
||||
Sampler* const sampler{texture_cache.GetGraphicsSampler(handle.second)};
|
||||
samplers[samplers_index++] = sampler;
|
||||
samplers[sampler_binding++] = sampler->Handle();
|
||||
}
|
||||
}
|
||||
if constexpr (Spec::has_images) {
|
||||
|
@ -444,13 +445,10 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
|
|||
program_manager.BindSourcePrograms(source_programs);
|
||||
}
|
||||
const VideoCommon::ImageViewInOut* views_it{views.data()};
|
||||
const Sampler** samplers_it{samplers.data()};
|
||||
GLsizei texture_binding = 0;
|
||||
GLsizei image_binding = 0;
|
||||
GLsizei sampler_binding{};
|
||||
std::array<GLuint, MAX_TEXTURES> textures;
|
||||
std::array<GLuint, MAX_IMAGES> images;
|
||||
std::array<GLuint, MAX_TEXTURES> gl_samplers;
|
||||
const auto prepare_stage{[&](size_t stage) {
|
||||
buffer_cache.runtime.SetImagePointers(&textures[texture_binding], &images[image_binding]);
|
||||
buffer_cache.BindHostStageBuffers(stage);
|
||||
|
@ -467,13 +465,6 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
|
|||
u32 stage_image_binding{};
|
||||
|
||||
const auto& info{stage_infos[stage]};
|
||||
if constexpr (Spec::has_texture_buffers) {
|
||||
for (const auto& desc : info.texture_buffer_descriptors) {
|
||||
for (u32 index = 0; index < desc.count; ++index) {
|
||||
gl_samplers[sampler_binding++] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const auto& desc : info.texture_descriptors) {
|
||||
for (u32 index = 0; index < desc.count; ++index) {
|
||||
ImageView& image_view{texture_cache.GetImageView((views_it++)->id)};
|
||||
|
@ -483,12 +474,6 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
|
|||
}
|
||||
++texture_binding;
|
||||
++stage_texture_binding;
|
||||
|
||||
const Sampler& sampler{**(samplers_it++)};
|
||||
const bool use_fallback_sampler{sampler.HasAddedAnisotropy() &&
|
||||
!image_view.SupportsAnisotropy()};
|
||||
gl_samplers[sampler_binding++] =
|
||||
use_fallback_sampler ? sampler.HandleWithDefaultAnisotropy() : sampler.Handle();
|
||||
}
|
||||
}
|
||||
for (const auto& desc : info.image_descriptors) {
|
||||
|
@ -549,7 +534,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
|
|||
if (texture_binding != 0) {
|
||||
ASSERT(texture_binding == sampler_binding);
|
||||
glBindTextures(0, texture_binding, textures.data());
|
||||
glBindSamplers(0, sampler_binding, gl_samplers.data());
|
||||
glBindSamplers(0, sampler_binding, samplers.data());
|
||||
}
|
||||
if (image_binding != 0) {
|
||||
glBindImageTextures(0, image_binding, images.data());
|
||||
|
|
|
@ -1268,48 +1268,36 @@ Sampler::Sampler(TextureCacheRuntime& runtime, const TSCEntry& config) {
|
|||
|
||||
UNIMPLEMENTED_IF(config.cubemap_anisotropy != 1);
|
||||
|
||||
const f32 max_anisotropy = std::clamp(config.MaxAnisotropy(), 1.0f, 16.0f);
|
||||
sampler.Create();
|
||||
const GLuint handle = sampler.handle;
|
||||
glSamplerParameteri(handle, GL_TEXTURE_WRAP_S, MaxwellToGL::WrapMode(config.wrap_u));
|
||||
glSamplerParameteri(handle, GL_TEXTURE_WRAP_T, MaxwellToGL::WrapMode(config.wrap_v));
|
||||
glSamplerParameteri(handle, GL_TEXTURE_WRAP_R, MaxwellToGL::WrapMode(config.wrap_p));
|
||||
glSamplerParameteri(handle, GL_TEXTURE_COMPARE_MODE, compare_mode);
|
||||
glSamplerParameteri(handle, GL_TEXTURE_COMPARE_FUNC, compare_func);
|
||||
glSamplerParameteri(handle, GL_TEXTURE_MAG_FILTER, mag);
|
||||
glSamplerParameteri(handle, GL_TEXTURE_MIN_FILTER, min);
|
||||
glSamplerParameterf(handle, GL_TEXTURE_LOD_BIAS, config.LodBias());
|
||||
glSamplerParameterf(handle, GL_TEXTURE_MIN_LOD, config.MinLod());
|
||||
glSamplerParameterf(handle, GL_TEXTURE_MAX_LOD, config.MaxLod());
|
||||
glSamplerParameterfv(handle, GL_TEXTURE_BORDER_COLOR, config.BorderColor().data());
|
||||
|
||||
const auto create_sampler = [&](const f32 anisotropy) {
|
||||
OGLSampler new_sampler;
|
||||
new_sampler.Create();
|
||||
const GLuint handle = new_sampler.handle;
|
||||
glSamplerParameteri(handle, GL_TEXTURE_WRAP_S, MaxwellToGL::WrapMode(config.wrap_u));
|
||||
glSamplerParameteri(handle, GL_TEXTURE_WRAP_T, MaxwellToGL::WrapMode(config.wrap_v));
|
||||
glSamplerParameteri(handle, GL_TEXTURE_WRAP_R, MaxwellToGL::WrapMode(config.wrap_p));
|
||||
glSamplerParameteri(handle, GL_TEXTURE_COMPARE_MODE, compare_mode);
|
||||
glSamplerParameteri(handle, GL_TEXTURE_COMPARE_FUNC, compare_func);
|
||||
glSamplerParameteri(handle, GL_TEXTURE_MAG_FILTER, mag);
|
||||
glSamplerParameteri(handle, GL_TEXTURE_MIN_FILTER, min);
|
||||
glSamplerParameterf(handle, GL_TEXTURE_LOD_BIAS, config.LodBias());
|
||||
glSamplerParameterf(handle, GL_TEXTURE_MIN_LOD, config.MinLod());
|
||||
glSamplerParameterf(handle, GL_TEXTURE_MAX_LOD, config.MaxLod());
|
||||
glSamplerParameterfv(handle, GL_TEXTURE_BORDER_COLOR, config.BorderColor().data());
|
||||
|
||||
if (GLAD_GL_ARB_texture_filter_anisotropic || GLAD_GL_EXT_texture_filter_anisotropic) {
|
||||
glSamplerParameterf(handle, GL_TEXTURE_MAX_ANISOTROPY, anisotropy);
|
||||
} else {
|
||||
LOG_WARNING(Render_OpenGL, "GL_ARB_texture_filter_anisotropic is required");
|
||||
}
|
||||
if (GLAD_GL_ARB_texture_filter_minmax || GLAD_GL_EXT_texture_filter_minmax) {
|
||||
glSamplerParameteri(handle, GL_TEXTURE_REDUCTION_MODE_ARB, reduction_filter);
|
||||
} else if (reduction_filter != GL_WEIGHTED_AVERAGE_ARB) {
|
||||
LOG_WARNING(Render_OpenGL, "GL_ARB_texture_filter_minmax is required");
|
||||
}
|
||||
if (GLAD_GL_ARB_seamless_cubemap_per_texture || GLAD_GL_AMD_seamless_cubemap_per_texture) {
|
||||
glSamplerParameteri(handle, GL_TEXTURE_CUBE_MAP_SEAMLESS, seamless);
|
||||
} else if (seamless == GL_FALSE) {
|
||||
// We default to false because it's more common
|
||||
LOG_WARNING(Render_OpenGL, "GL_ARB_seamless_cubemap_per_texture is required");
|
||||
}
|
||||
return new_sampler;
|
||||
};
|
||||
|
||||
sampler = create_sampler(max_anisotropy);
|
||||
|
||||
const f32 max_anisotropy_default = static_cast<f32>(1U << config.max_anisotropy);
|
||||
if (max_anisotropy > max_anisotropy_default) {
|
||||
sampler_default_anisotropy = create_sampler(max_anisotropy_default);
|
||||
if (GLAD_GL_ARB_texture_filter_anisotropic || GLAD_GL_EXT_texture_filter_anisotropic) {
|
||||
const f32 max_anisotropy = std::clamp(config.MaxAnisotropy(), 1.0f, 16.0f);
|
||||
glSamplerParameterf(handle, GL_TEXTURE_MAX_ANISOTROPY, max_anisotropy);
|
||||
} else {
|
||||
LOG_WARNING(Render_OpenGL, "GL_ARB_texture_filter_anisotropic is required");
|
||||
}
|
||||
if (GLAD_GL_ARB_texture_filter_minmax || GLAD_GL_EXT_texture_filter_minmax) {
|
||||
glSamplerParameteri(handle, GL_TEXTURE_REDUCTION_MODE_ARB, reduction_filter);
|
||||
} else if (reduction_filter != GL_WEIGHTED_AVERAGE_ARB) {
|
||||
LOG_WARNING(Render_OpenGL, "GL_ARB_texture_filter_minmax is required");
|
||||
}
|
||||
if (GLAD_GL_ARB_seamless_cubemap_per_texture || GLAD_GL_AMD_seamless_cubemap_per_texture) {
|
||||
glSamplerParameteri(handle, GL_TEXTURE_CUBE_MAP_SEAMLESS, seamless);
|
||||
} else if (seamless == GL_FALSE) {
|
||||
// We default to false because it's more common
|
||||
LOG_WARNING(Render_OpenGL, "GL_ARB_seamless_cubemap_per_texture is required");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -309,21 +309,12 @@ class Sampler {
|
|||
public:
|
||||
explicit Sampler(TextureCacheRuntime&, const Tegra::Texture::TSCEntry&);
|
||||
|
||||
[[nodiscard]] GLuint Handle() const noexcept {
|
||||
GLuint Handle() const noexcept {
|
||||
return sampler.handle;
|
||||
}
|
||||
|
||||
[[nodiscard]] GLuint HandleWithDefaultAnisotropy() const noexcept {
|
||||
return sampler_default_anisotropy.handle;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool HasAddedAnisotropy() const noexcept {
|
||||
return static_cast<bool>(sampler_default_anisotropy.handle);
|
||||
}
|
||||
|
||||
private:
|
||||
OGLSampler sampler;
|
||||
OGLSampler sampler_default_anisotropy;
|
||||
};
|
||||
|
||||
class Framebuffer {
|
||||
|
|
|
@ -178,7 +178,7 @@ public:
|
|||
inline void PushImageDescriptors(TextureCache& texture_cache,
|
||||
GuestDescriptorQueue& guest_descriptor_queue,
|
||||
const Shader::Info& info, RescalingPushConstant& rescaling,
|
||||
const Sampler**& samplers,
|
||||
const VkSampler*& samplers,
|
||||
const VideoCommon::ImageViewInOut*& views) {
|
||||
const u32 num_texture_buffers = Shader::NumDescriptors(info.texture_buffer_descriptors);
|
||||
const u32 num_image_buffers = Shader::NumDescriptors(info.image_buffer_descriptors);
|
||||
|
@ -187,14 +187,10 @@ inline void PushImageDescriptors(TextureCache& texture_cache,
|
|||
for (const auto& desc : info.texture_descriptors) {
|
||||
for (u32 index = 0; index < desc.count; ++index) {
|
||||
const VideoCommon::ImageViewId image_view_id{(views++)->id};
|
||||
const VkSampler sampler{*(samplers++)};
|
||||
ImageView& image_view{texture_cache.GetImageView(image_view_id)};
|
||||
const VkImageView vk_image_view{image_view.Handle(desc.type)};
|
||||
const Sampler& sampler{**(samplers++)};
|
||||
const bool use_fallback_sampler{sampler.HasAddedAnisotropy() &&
|
||||
!image_view.SupportsAnisotropy()};
|
||||
const VkSampler vk_sampler{use_fallback_sampler ? sampler.HandleWithDefaultAnisotropy()
|
||||
: sampler.Handle()};
|
||||
guest_descriptor_queue.AddSampledImage(vk_image_view, vk_sampler);
|
||||
guest_descriptor_queue.AddSampledImage(vk_image_view, sampler);
|
||||
rescaling.PushTexture(texture_cache.IsRescaling(image_view));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -115,7 +115,7 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute,
|
|||
|
||||
static constexpr size_t max_elements = 64;
|
||||
boost::container::static_vector<VideoCommon::ImageViewInOut, max_elements> views;
|
||||
boost::container::static_vector<const Sampler*, max_elements> samplers;
|
||||
boost::container::static_vector<VkSampler, max_elements> samplers;
|
||||
|
||||
const auto& qmd{kepler_compute.launch_description};
|
||||
const auto& cbufs{qmd.const_buffer_config};
|
||||
|
@ -161,7 +161,7 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute,
|
|||
views.push_back({handle.first});
|
||||
|
||||
Sampler* const sampler = texture_cache.GetComputeSampler(handle.second);
|
||||
samplers.push_back(sampler);
|
||||
samplers.push_back(sampler->Handle());
|
||||
}
|
||||
}
|
||||
for (const auto& desc : info.image_descriptors) {
|
||||
|
@ -192,7 +192,7 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute,
|
|||
buffer_cache.BindHostComputeBuffers();
|
||||
|
||||
RescalingPushConstant rescaling;
|
||||
const Sampler** samplers_it{samplers.data()};
|
||||
const VkSampler* samplers_it{samplers.data()};
|
||||
const VideoCommon::ImageViewInOut* views_it{views.data()};
|
||||
PushImageDescriptors(texture_cache, guest_descriptor_queue, info, rescaling, samplers_it,
|
||||
views_it);
|
||||
|
|
|
@ -298,7 +298,7 @@ void GraphicsPipeline::AddTransition(GraphicsPipeline* transition) {
|
|||
template <typename Spec>
|
||||
void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
|
||||
std::array<VideoCommon::ImageViewInOut, MAX_IMAGE_ELEMENTS> views;
|
||||
std::array<const Sampler*, MAX_IMAGE_ELEMENTS> samplers;
|
||||
std::array<VkSampler, MAX_IMAGE_ELEMENTS> samplers;
|
||||
size_t sampler_index{};
|
||||
size_t view_index{};
|
||||
|
||||
|
@ -368,7 +368,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
|
|||
views[view_index++] = {handle.first};
|
||||
|
||||
Sampler* const sampler{texture_cache.GetGraphicsSampler(handle.second)};
|
||||
samplers[sampler_index++] = sampler;
|
||||
samplers[sampler_index++] = sampler->Handle();
|
||||
}
|
||||
}
|
||||
if constexpr (Spec::has_images) {
|
||||
|
@ -453,7 +453,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
|
|||
|
||||
RescalingPushConstant rescaling;
|
||||
RenderAreaPushConstant render_area;
|
||||
const Sampler** samplers_it{samplers.data()};
|
||||
const VkSampler* samplers_it{samplers.data()};
|
||||
const VideoCommon::ImageViewInOut* views_it{views.data()};
|
||||
const auto prepare_stage{[&](size_t stage) LAMBDA_FORCEINLINE {
|
||||
buffer_cache.BindHostStageBuffers(stage);
|
||||
|
|
|
@ -1803,36 +1803,27 @@ Sampler::Sampler(TextureCacheRuntime& runtime, const Tegra::Texture::TSCEntry& t
|
|||
// Some games have samplers with garbage. Sanitize them here.
|
||||
const f32 max_anisotropy = std::clamp(tsc.MaxAnisotropy(), 1.0f, 16.0f);
|
||||
|
||||
const auto create_sampler = [&](const f32 anisotropy) {
|
||||
return device.GetLogical().CreateSampler(VkSamplerCreateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
|
||||
.pNext = pnext,
|
||||
.flags = 0,
|
||||
.magFilter = MaxwellToVK::Sampler::Filter(tsc.mag_filter),
|
||||
.minFilter = MaxwellToVK::Sampler::Filter(tsc.min_filter),
|
||||
.mipmapMode = MaxwellToVK::Sampler::MipmapMode(tsc.mipmap_filter),
|
||||
.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>(anisotropy > 1.0f ? VK_TRUE : VK_FALSE),
|
||||
.maxAnisotropy = anisotropy,
|
||||
.compareEnable = 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 =
|
||||
arbitrary_borders ? VK_BORDER_COLOR_FLOAT_CUSTOM_EXT : ConvertBorderColor(color),
|
||||
.unnormalizedCoordinates = VK_FALSE,
|
||||
});
|
||||
};
|
||||
|
||||
sampler = create_sampler(max_anisotropy);
|
||||
|
||||
const f32 max_anisotropy_default = static_cast<f32>(1U << tsc.max_anisotropy);
|
||||
if (max_anisotropy > max_anisotropy_default) {
|
||||
sampler_default_anisotropy = create_sampler(max_anisotropy_default);
|
||||
}
|
||||
sampler = device.GetLogical().CreateSampler(VkSamplerCreateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
|
||||
.pNext = pnext,
|
||||
.flags = 0,
|
||||
.magFilter = MaxwellToVK::Sampler::Filter(tsc.mag_filter),
|
||||
.minFilter = MaxwellToVK::Sampler::Filter(tsc.min_filter),
|
||||
.mipmapMode = MaxwellToVK::Sampler::MipmapMode(tsc.mipmap_filter),
|
||||
.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>(max_anisotropy > 1.0f ? VK_TRUE : VK_FALSE),
|
||||
.maxAnisotropy = max_anisotropy,
|
||||
.compareEnable = 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 =
|
||||
arbitrary_borders ? VK_BORDER_COLOR_FLOAT_CUSTOM_EXT : ConvertBorderColor(color),
|
||||
.unnormalizedCoordinates = VK_FALSE,
|
||||
});
|
||||
}
|
||||
|
||||
Framebuffer::Framebuffer(TextureCacheRuntime& runtime, std::span<ImageView*, NUM_RT> color_buffers,
|
||||
|
|
|
@ -279,17 +279,8 @@ public:
|
|||
return *sampler;
|
||||
}
|
||||
|
||||
[[nodiscard]] VkSampler HandleWithDefaultAnisotropy() const noexcept {
|
||||
return *sampler_default_anisotropy;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool HasAddedAnisotropy() const noexcept {
|
||||
return static_cast<bool>(sampler_default_anisotropy);
|
||||
}
|
||||
|
||||
private:
|
||||
vk::Sampler sampler;
|
||||
vk::Sampler sampler_default_anisotropy;
|
||||
};
|
||||
|
||||
class Framebuffer {
|
||||
|
|
|
@ -45,52 +45,4 @@ ImageViewBase::ImageViewBase(const ImageInfo& info, const ImageViewInfo& view_in
|
|||
|
||||
ImageViewBase::ImageViewBase(const NullImageViewParams&) : image_id{NULL_IMAGE_ID} {}
|
||||
|
||||
bool ImageViewBase::SupportsAnisotropy() const noexcept {
|
||||
using namespace VideoCommon;
|
||||
switch (format) {
|
||||
case PixelFormat::R8_UNORM:
|
||||
case PixelFormat::R8_SNORM:
|
||||
case PixelFormat::R8_SINT:
|
||||
case PixelFormat::R8_UINT:
|
||||
case PixelFormat::BC4_UNORM:
|
||||
case PixelFormat::BC4_SNORM:
|
||||
case PixelFormat::BC5_UNORM:
|
||||
case PixelFormat::BC5_SNORM:
|
||||
case PixelFormat::R32G32_FLOAT:
|
||||
case PixelFormat::R32G32_SINT:
|
||||
case PixelFormat::R32_FLOAT:
|
||||
case PixelFormat::R16_FLOAT:
|
||||
case PixelFormat::R16_UNORM:
|
||||
case PixelFormat::R16_SNORM:
|
||||
case PixelFormat::R16_UINT:
|
||||
case PixelFormat::R16_SINT:
|
||||
case PixelFormat::R16G16_UNORM:
|
||||
case PixelFormat::R16G16_FLOAT:
|
||||
case PixelFormat::R16G16_UINT:
|
||||
case PixelFormat::R16G16_SINT:
|
||||
case PixelFormat::R16G16_SNORM:
|
||||
case PixelFormat::R8G8_UNORM:
|
||||
case PixelFormat::R8G8_SNORM:
|
||||
case PixelFormat::R8G8_SINT:
|
||||
case PixelFormat::R8G8_UINT:
|
||||
case PixelFormat::R32G32_UINT:
|
||||
case PixelFormat::R32_UINT:
|
||||
case PixelFormat::R32_SINT:
|
||||
case PixelFormat::G4R4_UNORM:
|
||||
// Depth formats
|
||||
case PixelFormat::D32_FLOAT:
|
||||
case PixelFormat::D16_UNORM:
|
||||
// Stencil formats
|
||||
case PixelFormat::S8_UINT:
|
||||
// DepthStencil formats
|
||||
case PixelFormat::D24_UNORM_S8_UINT:
|
||||
case PixelFormat::S8_UINT_D24_UNORM:
|
||||
case PixelFormat::D32_FLOAT_S8_UINT:
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return range.extent.levels > 1;
|
||||
}
|
||||
|
||||
} // namespace VideoCommon
|
||||
|
|
|
@ -33,8 +33,6 @@ struct ImageViewBase {
|
|||
return type == ImageViewType::Buffer;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool SupportsAnisotropy() const noexcept;
|
||||
|
||||
ImageId image_id{};
|
||||
GPUVAddr gpu_addr = 0;
|
||||
PixelFormat format{};
|
||||
|
|
|
@ -186,6 +186,10 @@ void TextureCache<P>::FillComputeImageViews(std::span<ImageViewInOut> views) {
|
|||
|
||||
template <class P>
|
||||
void TextureCache<P>::CheckFeedbackLoop(std::span<const ImageViewInOut> views) {
|
||||
if (!Settings::values.barrier_feedback_loops.GetValue()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const bool requires_barrier = [&] {
|
||||
for (const auto& view : views) {
|
||||
if (!view.id) {
|
||||
|
|
|
@ -62,14 +62,7 @@ std::array<float, 4> TSCEntry::BorderColor() const noexcept {
|
|||
}
|
||||
|
||||
float TSCEntry::MaxAnisotropy() const noexcept {
|
||||
const bool is_suitable_mipmap_filter = Settings::values.use_aggressive_anisotropic_filtering
|
||||
? mipmap_filter != TextureMipmapFilter::None
|
||||
: mipmap_filter == TextureMipmapFilter::Linear;
|
||||
const bool has_regular_lods = min_lod_clamp == 0 && max_lod_clamp >= 256;
|
||||
const bool is_bilinear_filter = min_filter == TextureFilter::Linear &&
|
||||
reduction_filter == SamplerReduction::WeightedAverage;
|
||||
if (max_anisotropy == 0 && (depth_compare_enabled || !has_regular_lods || !is_bilinear_filter ||
|
||||
!is_suitable_mipmap_filter)) {
|
||||
if (max_anisotropy == 0 && mipmap_filter != TextureMipmapFilter::Linear) {
|
||||
return 1.0f;
|
||||
}
|
||||
const auto anisotropic_settings = Settings::values.max_anisotropy.GetValue();
|
||||
|
|
|
@ -345,6 +345,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
|
|||
const bool is_qualcomm = driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY;
|
||||
const bool is_turnip = driver_id == VK_DRIVER_ID_MESA_TURNIP;
|
||||
const bool is_s8gen2 = device_id == 0x43050a01;
|
||||
const bool is_arm = driver_id == VK_DRIVER_ID_ARM_PROPRIETARY;
|
||||
|
||||
if ((is_mvk || is_qualcomm || is_turnip) && !is_suitable) {
|
||||
LOG_WARNING(Render_Vulkan, "Unsuitable driver, continuing anyway");
|
||||
|
@ -392,7 +393,6 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
|
|||
CollectPhysicalMemoryInfo();
|
||||
CollectToolingInfo();
|
||||
|
||||
#ifdef ANDROID
|
||||
if (is_qualcomm || is_turnip) {
|
||||
LOG_WARNING(Render_Vulkan,
|
||||
"Qualcomm and Turnip drivers have broken VK_EXT_custom_border_color");
|
||||
|
@ -412,7 +412,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
|
|||
extensions.push_descriptor = false;
|
||||
loaded_extensions.erase(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
|
||||
|
||||
#ifdef ARCHITECTURE_arm64
|
||||
#if defined(ANDROID) && defined(ARCHITECTURE_arm64)
|
||||
// Patch the driver to enable BCn textures.
|
||||
const auto major = (properties.properties.driverVersion >> 24) << 2;
|
||||
const auto minor = (properties.properties.driverVersion >> 12) & 0xFFFU;
|
||||
|
@ -432,18 +432,23 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
|
|||
} else {
|
||||
LOG_WARNING(Render_Vulkan, "Adreno driver can't be patched to enable BCn textures");
|
||||
}
|
||||
#endif // ARCHITECTURE_arm64
|
||||
#endif
|
||||
}
|
||||
|
||||
const bool is_arm = driver_id == VK_DRIVER_ID_ARM_PROPRIETARY;
|
||||
if (is_arm) {
|
||||
must_emulate_scaled_formats = true;
|
||||
|
||||
LOG_WARNING(Render_Vulkan, "ARM drivers have broken VK_EXT_extended_dynamic_state");
|
||||
extensions.extended_dynamic_state = false;
|
||||
loaded_extensions.erase(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME);
|
||||
|
||||
LOG_WARNING(Render_Vulkan, "ARM drivers have broken VK_EXT_extended_dynamic_state2");
|
||||
features.extended_dynamic_state2.extendedDynamicState2 = false;
|
||||
features.extended_dynamic_state2.extendedDynamicState2LogicOp = false;
|
||||
features.extended_dynamic_state2.extendedDynamicState2PatchControlPoints = false;
|
||||
extensions.extended_dynamic_state2 = false;
|
||||
loaded_extensions.erase(VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME);
|
||||
}
|
||||
#endif // ANDROID
|
||||
|
||||
if (is_nvidia) {
|
||||
const u32 nv_major_version = (properties.properties.driverVersion >> 22) & 0x3ff;
|
||||
|
|
|
@ -761,7 +761,7 @@ void Config::ReadRendererValues() {
|
|||
ReadGlobalSetting(Settings::values.use_vulkan_driver_pipeline_cache);
|
||||
ReadGlobalSetting(Settings::values.enable_compute_pipelines);
|
||||
ReadGlobalSetting(Settings::values.use_video_framerate);
|
||||
ReadGlobalSetting(Settings::values.use_aggressive_anisotropic_filtering);
|
||||
ReadGlobalSetting(Settings::values.barrier_feedback_loops);
|
||||
ReadGlobalSetting(Settings::values.bg_red);
|
||||
ReadGlobalSetting(Settings::values.bg_green);
|
||||
ReadGlobalSetting(Settings::values.bg_blue);
|
||||
|
@ -1418,7 +1418,7 @@ void Config::SaveRendererValues() {
|
|||
WriteGlobalSetting(Settings::values.use_vulkan_driver_pipeline_cache);
|
||||
WriteGlobalSetting(Settings::values.enable_compute_pipelines);
|
||||
WriteGlobalSetting(Settings::values.use_video_framerate);
|
||||
WriteGlobalSetting(Settings::values.use_aggressive_anisotropic_filtering);
|
||||
WriteGlobalSetting(Settings::values.barrier_feedback_loops);
|
||||
WriteGlobalSetting(Settings::values.bg_red);
|
||||
WriteGlobalSetting(Settings::values.bg_green);
|
||||
WriteGlobalSetting(Settings::values.bg_blue);
|
||||
|
|
|
@ -31,7 +31,6 @@ void ConfigureGraphicsAdvanced::SetConfiguration() {
|
|||
ui->use_asynchronous_shaders->setEnabled(runtime_lock);
|
||||
ui->anisotropic_filtering_combobox->setEnabled(runtime_lock);
|
||||
ui->enable_compute_pipelines_checkbox->setEnabled(runtime_lock);
|
||||
ui->use_aggressive_anisotropic_filtering->setEnabled(runtime_lock);
|
||||
|
||||
ui->async_present->setChecked(Settings::values.async_presentation.GetValue());
|
||||
ui->renderer_force_max_clock->setChecked(Settings::values.renderer_force_max_clock.GetValue());
|
||||
|
@ -44,8 +43,8 @@ void ConfigureGraphicsAdvanced::SetConfiguration() {
|
|||
ui->enable_compute_pipelines_checkbox->setChecked(
|
||||
Settings::values.enable_compute_pipelines.GetValue());
|
||||
ui->use_video_framerate_checkbox->setChecked(Settings::values.use_video_framerate.GetValue());
|
||||
ui->use_aggressive_anisotropic_filtering->setChecked(
|
||||
Settings::values.use_aggressive_anisotropic_filtering.GetValue());
|
||||
ui->barrier_feedback_loops_checkbox->setChecked(
|
||||
Settings::values.barrier_feedback_loops.GetValue());
|
||||
|
||||
if (Settings::IsConfiguringGlobal()) {
|
||||
ui->gpu_accuracy->setCurrentIndex(
|
||||
|
@ -97,9 +96,9 @@ void ConfigureGraphicsAdvanced::ApplyConfiguration() {
|
|||
enable_compute_pipelines);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_video_framerate,
|
||||
ui->use_video_framerate_checkbox, use_video_framerate);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_aggressive_anisotropic_filtering,
|
||||
ui->use_aggressive_anisotropic_filtering,
|
||||
use_aggressive_anisotropic_filtering);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.barrier_feedback_loops,
|
||||
ui->barrier_feedback_loops_checkbox,
|
||||
barrier_feedback_loops);
|
||||
}
|
||||
|
||||
void ConfigureGraphicsAdvanced::changeEvent(QEvent* event) {
|
||||
|
@ -136,8 +135,8 @@ void ConfigureGraphicsAdvanced::SetupPerGameUI() {
|
|||
Settings::values.enable_compute_pipelines.UsingGlobal());
|
||||
ui->use_video_framerate_checkbox->setEnabled(
|
||||
Settings::values.use_video_framerate.UsingGlobal());
|
||||
ui->use_aggressive_anisotropic_filtering->setEnabled(
|
||||
Settings::values.use_aggressive_anisotropic_filtering.UsingGlobal());
|
||||
ui->barrier_feedback_loops_checkbox->setEnabled(
|
||||
Settings::values.barrier_feedback_loops.UsingGlobal());
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -165,9 +164,9 @@ void ConfigureGraphicsAdvanced::SetupPerGameUI() {
|
|||
ConfigurationShared::SetColoredTristate(ui->use_video_framerate_checkbox,
|
||||
Settings::values.use_video_framerate,
|
||||
use_video_framerate);
|
||||
ConfigurationShared::SetColoredTristate(ui->use_aggressive_anisotropic_filtering,
|
||||
Settings::values.use_aggressive_anisotropic_filtering,
|
||||
use_aggressive_anisotropic_filtering);
|
||||
ConfigurationShared::SetColoredTristate(ui->barrier_feedback_loops_checkbox,
|
||||
Settings::values.barrier_feedback_loops,
|
||||
barrier_feedback_loops);
|
||||
ConfigurationShared::SetColoredComboBox(
|
||||
ui->gpu_accuracy, ui->label_gpu_accuracy,
|
||||
static_cast<int>(Settings::values.gpu_accuracy.GetValue(true)));
|
||||
|
|
|
@ -48,7 +48,7 @@ private:
|
|||
ConfigurationShared::CheckState use_vulkan_driver_pipeline_cache;
|
||||
ConfigurationShared::CheckState enable_compute_pipelines;
|
||||
ConfigurationShared::CheckState use_video_framerate;
|
||||
ConfigurationShared::CheckState use_aggressive_anisotropic_filtering;
|
||||
ConfigurationShared::CheckState barrier_feedback_loops;
|
||||
|
||||
const Core::System& system;
|
||||
};
|
||||
|
|
|
@ -201,6 +201,16 @@ Compute pipelines are always enabled on all other drivers.</string>
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="barrier_feedback_loops_checkbox">
|
||||
<property name="toolTip">
|
||||
<string>Improves rendering of transparency effects in specific games.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Barrier feedback loops</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="af_layout" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_1">
|
||||
|
@ -260,19 +270,6 @@ Compute pipelines are always enabled on all other drivers.</string>
|
|||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="use_aggressive_anisotropic_filtering">
|
||||
<property name="toolTip">
|
||||
<string>Enable this option for a more aggressive approach to applying Anisotropic Filtering to textures.
|
||||
By toggling this, Anisotropic Filtering is added to textures with both nearest and linear mipmapping modes.
|
||||
This may result in improved visual quality for a wider range of textures, but can also introduce artifacts in
|
||||
some titles.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Apply Anisotropic Filtering for all mipmap modes</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
@ -321,7 +321,6 @@ void Config::ReadValues() {
|
|||
ReadSetting("Renderer", Settings::values.astc_recompression);
|
||||
ReadSetting("Renderer", Settings::values.use_fast_gpu_time);
|
||||
ReadSetting("Renderer", Settings::values.use_vulkan_driver_pipeline_cache);
|
||||
ReadSetting("Renderer", Settings::values.use_aggressive_anisotropic_filtering);
|
||||
|
||||
ReadSetting("Renderer", Settings::values.bg_red);
|
||||
ReadSetting("Renderer", Settings::values.bg_green);
|
||||
|
|
|
@ -325,10 +325,6 @@ aspect_ratio =
|
|||
# 0: Default, 1: 2x, 2: 4x, 3: 8x, 4: 16x
|
||||
max_anisotropy =
|
||||
|
||||
# Apply Anisotropic Filtering to all mipmap modes.
|
||||
# 0 (default): Off, 1: On
|
||||
use_aggressive_anisotropic_filtering =
|
||||
|
||||
# Whether to enable VSync or not.
|
||||
# OpenGL: Values other than 0 enable VSync
|
||||
# Vulkan: FIFO is selected if the requested mode is not supported by the driver.
|
||||
|
|
Loading…
Reference in a new issue