Browse Source

random fixes for random stuff

pull/2727/head
Ribbit 5 months ago
parent
commit
353d793622
  1. 6
      src/video_core/renderer_vulkan/pipeline_helper.h
  2. 5
      src/video_core/renderer_vulkan/vk_compute_pass.cpp
  3. 69
      src/video_core/renderer_vulkan/vk_texture_cache.cpp
  4. 11
      src/video_core/renderer_vulkan/vk_texture_cache.h

6
src/video_core/renderer_vulkan/pipeline_helper.h

@ -191,10 +191,8 @@ inline void PushImageDescriptors(TextureCache& texture_cache,
ImageView& image_view{texture_cache.GetImageView(image_view_id)}; ImageView& image_view{texture_cache.GetImageView(image_view_id)};
const VkImageView vk_image_view{image_view.Handle(desc.type)}; const VkImageView vk_image_view{image_view.Handle(desc.type)};
const Sampler& sampler{texture_cache.GetSampler(sampler_id)}; const Sampler& sampler{texture_cache.GetSampler(sampler_id)};
const bool use_fallback_sampler{sampler.HasAddedAnisotropy() &&
!image_view.SupportsAnisotropy()};
const VkSampler vk_sampler{use_fallback_sampler ? sampler.HandleWithDefaultAnisotropy()
: sampler.Handle()};
const VkSampler vk_sampler{sampler.HandleForView(image_view.SupportsLinearFiltering(),
image_view.SupportsAnisotropy())};
guest_descriptor_queue.AddSampledImage(vk_image_view, vk_sampler); guest_descriptor_queue.AddSampledImage(vk_image_view, vk_sampler);
rescaling.PushTexture(texture_cache.IsRescaling(image_view)); rescaling.PushTexture(texture_cache.IsRescaling(image_view));
} }

5
src/video_core/renderer_vulkan/vk_compute_pass.cpp

@ -503,6 +503,8 @@ void QueriesPrefixScanPass::Run(VkBuffer accumulation_buffer, VkBuffer dst_buffe
VK_ACCESS_UNIFORM_READ_BIT | VK_ACCESS_UNIFORM_READ_BIT |
VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT, VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT,
}; };
static constexpr VkPipelineStageFlags write_dest_stages =
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; // dstAccessMask spans many stages
const QueriesPrefixScanPushConstants uniforms{ const QueriesPrefixScanPushConstants uniforms{
.min_accumulation_base = static_cast<u32>(min_accumulation_limit), .min_accumulation_base = static_cast<u32>(min_accumulation_limit),
.max_accumulation_base = static_cast<u32>(max_accumulation_limit), .max_accumulation_base = static_cast<u32>(max_accumulation_limit),
@ -519,8 +521,7 @@ void QueriesPrefixScanPass::Run(VkBuffer accumulation_buffer, VkBuffer dst_buffe
cmdbuf.PushConstants(*layout, VK_SHADER_STAGE_COMPUTE_BIT, uniforms); cmdbuf.PushConstants(*layout, VK_SHADER_STAGE_COMPUTE_BIT, uniforms);
cmdbuf.Dispatch(1, 1, 1); cmdbuf.Dispatch(1, 1, 1);
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT, 0,
write_barrier);
write_dest_stages, 0, write_barrier);
}); });
} }
} }

69
src/video_core/renderer_vulkan/vk_texture_cache.cpp

@ -2030,6 +2030,8 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI
"Image view format {} has different usage flags than image format {}", format, "Image view format {} has different usage flags than image format {}", format,
image.info.format); image.info.format);
} }
supports_linear_filtering = device->IsFormatSupported(
format_info.format, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT, FormatType::Optimal);
const VkImageViewUsageCreateInfo image_view_usage{ const VkImageViewUsageCreateInfo image_view_usage{
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
@ -2100,7 +2102,8 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI
ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageInfo& info, ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageInfo& info,
const VideoCommon::ImageViewInfo& view_info, GPUVAddr gpu_addr_) const VideoCommon::ImageViewInfo& view_info, GPUVAddr gpu_addr_)
: VideoCommon::ImageViewBase{info, view_info, gpu_addr_}, : VideoCommon::ImageViewBase{info, view_info, gpu_addr_},
buffer_size{VideoCommon::CalculateGuestSizeInBytes(info)} {}
buffer_size{VideoCommon::CalculateGuestSizeInBytes(info)},
supports_linear_filtering{false} {}
ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::NullImageViewParams& params) ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::NullImageViewParams& params)
: VideoCommon::ImageViewBase{params}, device{&runtime.device} { : VideoCommon::ImageViewBase{params}, device{&runtime.device} {
@ -2161,20 +2164,31 @@ VkImageView ImageView::StorageView(Shader::TextureType texture_type,
if (!image_handle) { if (!image_handle) {
return VK_NULL_HANDLE; return VK_NULL_HANDLE;
} }
if (!storage_views) {
storage_views = std::make_unique<StorageViews>();
}
// For storage images, Vulkan requires identity-swizzled views regardless of sampling swizzles.
// - If the image is typeless in the shader, create an identity-swizzled view using the
// underlying image's format.
if (image_format == Shader::ImageFormat::Typeless) { if (image_format == Shader::ImageFormat::Typeless) {
return Handle(texture_type);
auto& view = storage_views->typeless[static_cast<size_t>(texture_type)];
if (!view) {
const auto format_info =
MaxwellToVK::SurfaceFormat(*device, FormatType::Optimal, true, format);
view = MakeView(format_info.format, VK_IMAGE_ASPECT_COLOR_BIT);
} }
return *view;
}
// Otherwise, use a typed storage view with identity swizzle.
const bool is_signed{image_format == Shader::ImageFormat::R8_SINT || const bool is_signed{image_format == Shader::ImageFormat::R8_SINT ||
image_format == Shader::ImageFormat::R16_SINT}; image_format == Shader::ImageFormat::R16_SINT};
if (!storage_views) {
storage_views = std::make_unique<StorageViews>();
}
auto& views{is_signed ? storage_views->signeds : storage_views->unsigneds}; auto& views{is_signed ? storage_views->signeds : storage_views->unsigneds};
auto& view{views[static_cast<size_t>(texture_type)]}; auto& view{views[static_cast<size_t>(texture_type)]};
if (view) {
return *view;
}
if (!view) {
view = MakeView(Format(image_format), VK_IMAGE_ASPECT_COLOR_BIT); view = MakeView(Format(image_format), VK_IMAGE_ASPECT_COLOR_BIT);
}
return *view; return *view;
} }
@ -2234,14 +2248,19 @@ Sampler::Sampler(TextureCacheRuntime& runtime, const Tegra::Texture::TSCEntry& t
// Some games have samplers with garbage. Sanitize them here. // Some games have samplers with garbage. Sanitize them here.
const f32 max_anisotropy = std::clamp(tsc.MaxAnisotropy(), 1.0f, 16.0f); const f32 max_anisotropy = std::clamp(tsc.MaxAnisotropy(), 1.0f, 16.0f);
const auto create_sampler = [&](const f32 anisotropy) {
const VkFilter mag_filter = MaxwellToVK::Sampler::Filter(tsc.mag_filter);
const VkFilter min_filter = MaxwellToVK::Sampler::Filter(tsc.min_filter);
const VkSamplerMipmapMode mipmap_mode = MaxwellToVK::Sampler::MipmapMode(tsc.mipmap_filter);
const auto create_sampler = [&](f32 anisotropy, VkFilter mag, VkFilter min,
VkSamplerMipmapMode mipmap) {
return device.GetLogical().CreateSampler(VkSamplerCreateInfo{ return device.GetLogical().CreateSampler(VkSamplerCreateInfo{
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
.pNext = pnext, .pNext = pnext,
.flags = 0, .flags = 0,
.magFilter = MaxwellToVK::Sampler::Filter(tsc.mag_filter),
.minFilter = MaxwellToVK::Sampler::Filter(tsc.min_filter),
.mipmapMode = MaxwellToVK::Sampler::MipmapMode(tsc.mipmap_filter),
.magFilter = mag,
.minFilter = min,
.mipmapMode = mipmap,
.addressModeU = MaxwellToVK::Sampler::WrapMode(device, tsc.wrap_u, tsc.mag_filter), .addressModeU = MaxwellToVK::Sampler::WrapMode(device, tsc.wrap_u, tsc.mag_filter),
.addressModeV = MaxwellToVK::Sampler::WrapMode(device, tsc.wrap_v, 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), .addressModeW = MaxwellToVK::Sampler::WrapMode(device, tsc.wrap_p, tsc.mag_filter),
@ -2258,12 +2277,34 @@ Sampler::Sampler(TextureCacheRuntime& runtime, const Tegra::Texture::TSCEntry& t
}); });
}; };
sampler = create_sampler(max_anisotropy);
sampler = create_sampler(max_anisotropy, mag_filter, min_filter, mipmap_mode);
const f32 max_anisotropy_default = static_cast<f32>(1U << tsc.max_anisotropy); const f32 max_anisotropy_default = static_cast<f32>(1U << tsc.max_anisotropy);
if (max_anisotropy > max_anisotropy_default) { if (max_anisotropy > max_anisotropy_default) {
sampler_default_anisotropy = create_sampler(max_anisotropy_default);
sampler_default_anisotropy =
create_sampler(max_anisotropy_default, mag_filter, min_filter, mipmap_mode);
}
const bool needs_linear_fallback = (mag_filter == VK_FILTER_LINEAR) ||
(min_filter == VK_FILTER_LINEAR) ||
(mipmap_mode == VK_SAMPLER_MIPMAP_MODE_LINEAR) ||
(max_anisotropy > 1.0f);
if (needs_linear_fallback) {
sampler_linear_fallback =
create_sampler(1.0f, VK_FILTER_NEAREST, VK_FILTER_NEAREST,
VK_SAMPLER_MIPMAP_MODE_NEAREST);
}
}
VkSampler Sampler::HandleForView(bool supports_linear_filter,
bool supports_anisotropy) const noexcept {
if (!supports_linear_filter && sampler_linear_fallback) {
return *sampler_linear_fallback;
}
if (!supports_anisotropy && sampler_default_anisotropy) {
return *sampler_default_anisotropy;
} }
return *sampler;
} }
Framebuffer::Framebuffer(TextureCacheRuntime& runtime, std::span<ImageView*, NUM_RT> color_buffers, Framebuffer::Framebuffer(TextureCacheRuntime& runtime, std::span<ImageView*, NUM_RT> color_buffers,

11
src/video_core/renderer_vulkan/vk_texture_cache.h

@ -258,6 +258,10 @@ public:
return gpu_addr; return gpu_addr;
} }
[[nodiscard]] bool SupportsLinearFiltering() const noexcept {
return supports_linear_filtering;
}
[[nodiscard]] u32 BufferSize() const noexcept { [[nodiscard]] u32 BufferSize() const noexcept {
return buffer_size; return buffer_size;
} }
@ -266,6 +270,8 @@ private:
struct StorageViews { struct StorageViews {
std::array<vk::ImageView, Shader::NUM_TEXTURE_TYPES> signeds; std::array<vk::ImageView, Shader::NUM_TEXTURE_TYPES> signeds;
std::array<vk::ImageView, Shader::NUM_TEXTURE_TYPES> unsigneds; std::array<vk::ImageView, Shader::NUM_TEXTURE_TYPES> unsigneds;
// Identity-swizzled views for typeless storage bindings
std::array<vk::ImageView, Shader::NUM_TEXTURE_TYPES> typeless;
}; };
[[nodiscard]] vk::ImageView MakeView(VkFormat vk_format, VkImageAspectFlags aspect_mask); [[nodiscard]] vk::ImageView MakeView(VkFormat vk_format, VkImageAspectFlags aspect_mask);
@ -283,6 +289,7 @@ private:
VkImageView render_target = VK_NULL_HANDLE; VkImageView render_target = VK_NULL_HANDLE;
VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT; VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT;
u32 buffer_size = 0; u32 buffer_size = 0;
bool supports_linear_filtering = true;
}; };
class ImageAlloc : public VideoCommon::ImageAllocBase {}; class ImageAlloc : public VideoCommon::ImageAllocBase {};
@ -303,9 +310,13 @@ public:
return static_cast<bool>(sampler_default_anisotropy); return static_cast<bool>(sampler_default_anisotropy);
} }
[[nodiscard]] VkSampler HandleForView(bool supports_linear_filter,
bool supports_anisotropy) const noexcept;
private: private:
vk::Sampler sampler; vk::Sampler sampler;
vk::Sampler sampler_default_anisotropy; vk::Sampler sampler_default_anisotropy;
vk::Sampler sampler_linear_fallback;
}; };
class Framebuffer { class Framebuffer {

Loading…
Cancel
Save