diff --git a/src/video_core/renderer_opengl/gl_compute_pipeline.cpp b/src/video_core/renderer_opengl/gl_compute_pipeline.cpp index d1c61be743..6625d0eb6b 100644 --- a/src/video_core/renderer_opengl/gl_compute_pipeline.cpp +++ b/src/video_core/renderer_opengl/gl_compute_pipeline.cpp @@ -210,7 +210,8 @@ void ComputePipeline::Configure() { for (const auto& desc : info.texture_descriptors) { for (u32 index = 0; index < desc.count; ++index) { ImageView& image_view{texture_cache.GetImageView((views_it++)->id)}; - textures[texture_binding] = image_view.Handle(desc.type); + textures[texture_binding] = + image_view.SampledView(desc.type, desc.component_type); if (texture_cache.IsRescaling(image_view)) { texture_scaling_mask |= 1u << texture_binding; } diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp index ee3498428e..30621c6511 100644 --- a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp +++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp @@ -481,7 +481,8 @@ bool GraphicsPipeline::ConfigureImpl(bool is_indexed) { for (const auto& desc : info.texture_descriptors) { for (u32 index = 0; index < desc.count; ++index) { ImageView& image_view{texture_cache.GetImageView((views_it++)->id)}; - textures[texture_binding] = image_view.Handle(desc.type); + textures[texture_binding] = + image_view.SampledView(desc.type, desc.component_type); if (texture_cache.IsRescaling(image_view)) { texture_scaling_mask |= 1u << stage_texture_binding; } diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index 958988f27e..3a5335f0cf 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp @@ -1227,6 +1227,13 @@ GLuint ImageView::StorageView(Shader::TextureType texture_type, Shader::ImageFor return view; } +GLuint ImageView::SampledView(Shader::TextureType view_type, + Shader::SamplerComponentType /*component_type*/) { + // OpenGL swizzles already configure depth/stencil selection per TIC entry, + // so fall back to the default view handle. + return Handle(view_type); +} + void ImageView::SetupView(Shader::TextureType view_type) { views[static_cast(view_type)] = MakeView(view_type, internal_format); } diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h index dfcef4b0b6..661227a1fa 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.h +++ b/src/video_core/renderer_opengl/gl_texture_cache.h @@ -270,6 +270,9 @@ public: [[nodiscard]] GLuint StorageView(Shader::TextureType texture_type, Shader::ImageFormat image_format); + [[nodiscard]] GLuint SampledView(Shader::TextureType view_type, + Shader::SamplerComponentType component_type); + [[nodiscard]] GLuint Handle(Shader::TextureType handle_type) const noexcept { return views[static_cast(handle_type)]; } diff --git a/src/video_core/renderer_vulkan/pipeline_helper.h b/src/video_core/renderer_vulkan/pipeline_helper.h index e88b27b273..d74cd6541e 100644 --- a/src/video_core/renderer_vulkan/pipeline_helper.h +++ b/src/video_core/renderer_vulkan/pipeline_helper.h @@ -193,7 +193,8 @@ inline void PushImageDescriptors(TextureCache& texture_cache, const VideoCommon::ImageViewId image_view_id{(views++)->id}; const VideoCommon::SamplerId sampler_id{*(samplers++)}; 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.SampledView(desc.type, desc.component_type)}; const Sampler& sampler{texture_cache.GetSampler(sampler_id)}; const bool use_fallback_sampler{sampler.HasAddedAnisotropy() && !image_view.SupportsAnisotropy()}; diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index e65d594c31..0a1fb49890 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -2297,6 +2297,29 @@ VkImageView ImageView::ColorView() { return *color_view; } +VkImageView ImageView::SampledView(Shader::TextureType texture_type, + Shader::SamplerComponentType component_type) { + using VideoCore::Surface::GetFormatType; + using VideoCore::Surface::SurfaceType; + + const SurfaceType surface_type = GetFormatType(format); + switch (component_type) { + case Shader::SamplerComponentType::Depth: + if (surface_type == SurfaceType::Depth || surface_type == SurfaceType::DepthStencil) { + return DepthView(); + } + break; + case Shader::SamplerComponentType::Stencil: + if (surface_type == SurfaceType::Stencil || surface_type == SurfaceType::DepthStencil) { + return StencilView(); + } + break; + default: + break; + } + return Handle(texture_type); +} + VkImageView ImageView::StorageView(Shader::TextureType texture_type, Shader::ImageFormat image_format) { if (image_handle) { diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h index f102ee5222..9d8917a6a6 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.h +++ b/src/video_core/renderer_vulkan/vk_texture_cache.h @@ -114,6 +114,10 @@ public: return view_formats[static_cast(format)]; } + bool RequiresBlockCompatibleViewFormats(PixelFormat format) const noexcept { + return requires_block_view_formats[static_cast(format)]; + } + void BarrierFeedbackLoop(); bool IsFormatDitherable(VideoCore::Surface::PixelFormat format); @@ -137,6 +141,7 @@ public: std::optional msaa_copy_pass; const Settings::ResolutionScalingInfo& resolution; std::array, VideoCore::Surface::MaxPixelFormat> view_formats; + std::array requires_block_view_formats{}; static constexpr size_t indexing_slots = 8 * sizeof(size_t); std::array buffers{}; @@ -268,6 +273,30 @@ public: return (this->*current_image).UsageFlags(); } + void TrackGpuReadTick(u64 tick) noexcept { + TrackPendingReadTick(tick); + } + + void TrackGpuWriteTick(u64 tick) noexcept { + TrackPendingWriteTick(tick); + } + + void CompleteGpuReadTick(u64 completed_tick) noexcept { + ClearPendingReadTick(completed_tick); + } + + void CompleteGpuWriteTick(u64 completed_tick) noexcept { + ClearPendingWriteTick(completed_tick); + } + + [[nodiscard]] std::optional PendingGpuReadTick() const noexcept { + return PendingReadTick(); + } + + [[nodiscard]] std::optional PendingGpuWriteTick() const noexcept { + return PendingWriteTick(); + } + /// Returns true when the image is already initialized and mark it as initialized [[nodiscard]] bool ExchangeInitialization() noexcept { return std::exchange(initialized, true); @@ -339,11 +368,16 @@ public: [[nodiscard]] VkImageView ColorView(); - [[nodiscard]] VkImageView StorageView(Shader::TextureType texture_type, - Shader::ImageFormat image_format); + [[nodiscard]] VkImageView SampledView(Shader::TextureType texture_type, Shader::SamplerComponentType component_type); + [[nodiscard]] VkImageView StorageView(Shader::TextureType texture_type, Shader::ImageFormat image_format); [[nodiscard]] bool IsRescaled() const noexcept; + [[nodiscard]] bool SupportsDepthCompareSampling() const noexcept; + [[nodiscard]] bool Is3DImage() const noexcept { + return is_3d_image; + } + [[nodiscard]] VkImageView Handle(Shader::TextureType texture_type) const noexcept { return *image_views[static_cast(texture_type)]; } @@ -372,15 +406,26 @@ private: struct StorageViews { std::array signeds; std::array unsigneds; + std::array typeless; }; - [[nodiscard]] vk::ImageView MakeView(VkFormat vk_format, VkImageAspectFlags aspect_mask); + static constexpr size_t NUMERIC_VIEW_TYPES = 3; + + [[nodiscard]] Shader::TextureType BaseTextureType() const noexcept; + [[nodiscard]] std::optional LayerCountOverride(Shader::TextureType texture_type) const noexcept; + [[nodiscard]] VkImageView DepthView(Shader::TextureType texture_type); + [[nodiscard]] VkImageView StencilView(Shader::TextureType texture_type); + [[nodiscard]] vk::ImageView MakeView(VkFormat vk_format, VkImageAspectFlags aspect_mask); + [[nodiscard]] vk::ImageView MakeView(VkFormat vk_format, VkImageAspectFlags aspect_mask, Shader::TextureType texture_type); const Device* device = nullptr; const SlotVector* slot_images = nullptr; std::array image_views; std::optional storage_views; + std::array depth_views; + std::array stencil_views; + std::array, NUMERIC_VIEW_TYPES> sampled_component_views; vk::ImageView depth_view; vk::ImageView stencil_view; vk::ImageView color_view; @@ -389,6 +434,7 @@ private: VkImageView render_target = VK_NULL_HANDLE; VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT; u32 buffer_size = 0; + bool is_3d_image = false; }; class ImageAlloc : public VideoCommon::ImageAllocBase {}; @@ -406,12 +452,20 @@ public: } [[nodiscard]] bool HasAddedAnisotropy() const noexcept { - return static_cast(sampler_default_anisotropy); + return bool(sampler_default_anisotropy); } + [[nodiscard]] VkSampler SelectHandle(bool supports_linear_filter, bool supports_anisotropy, bool allow_depth_compare) const noexcept; + private: vk::Sampler sampler; vk::Sampler sampler_default_anisotropy; + vk::Sampler sampler_force_point; + vk::Sampler sampler_compare_disabled; + vk::Sampler sampler_default_anisotropy_compare_disabled; + vk::Sampler sampler_force_point_compare_disabled; + bool uses_linear_filter = false; + bool depth_compare_enabled = false; }; struct TextureCacheParams {