diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index 75254049a6..4e771e21ac 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp @@ -1214,19 +1214,16 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::NullImageV ImageView::~ImageView() = default; GLuint ImageView::StorageView(Shader::TextureType texture_type, Shader::ImageFormat image_format) { - if (image_format == Shader::ImageFormat::Typeless) { + if (image_format == Shader::ImageFormat::Typeless) return Handle(texture_type); - } - const bool is_signed{image_format == Shader::ImageFormat::R8_SINT || - image_format == Shader::ImageFormat::R16_SINT}; - if (!storage_views) { - storage_views = std::make_unique(); - } + const bool is_signed = image_format == Shader::ImageFormat::R8_SINT + || image_format == Shader::ImageFormat::R16_SINT; + if (!storage_views) + storage_views = std::make_optional(); auto& type_views{is_signed ? storage_views->signeds : storage_views->unsigneds}; - GLuint& view{type_views[static_cast(texture_type)]}; - if (view == 0) { + GLuint& view{type_views[size_t(texture_type)]}; + if (view == 0) view = MakeView(texture_type, ShaderFormat(image_format)); - } return view; } diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h index 3de24508fe..e2a2022cb2 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.h +++ b/src/video_core/renderer_opengl/gl_texture_cache.h @@ -302,7 +302,7 @@ private: std::array views{}; std::vector stored_views; - std::unique_ptr storage_views; + std::optional storage_views; GLenum internal_format = GL_NONE; GLuint default_handle = 0; u32 buffer_size = 0; diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 101a884fd7..c3a5ed391b 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -376,7 +376,6 @@ void RasterizerVulkan::DrawTexture() { } void RasterizerVulkan::Clear(u32 layer_count) { - FlushWork(); gpu_memory->FlushCaching(); @@ -396,9 +395,7 @@ void RasterizerVulkan::Clear(u32 layer_count) { scheduler.RequestRenderpass(framebuffer); query_cache.NotifySegment(true); - query_cache.CounterEnable(VideoCommon::QueryType::ZPassPixelCount64, - maxwell3d->regs.zpass_pixel_count_enable); - + query_cache.CounterEnable(VideoCommon::QueryType::ZPassPixelCount64, maxwell3d->regs.zpass_pixel_count_enable); u32 up_scale = 1; u32 down_shift = 0; if (texture_cache.IsRescaling()) { @@ -443,14 +440,14 @@ void RasterizerVulkan::Clear(u32 layer_count) { offset = 0; return; } - if (offset >= static_cast(limit)) { - offset = static_cast(limit); + if (offset >= s32(limit)) { + offset = s32(limit); extent = 0; return; } - const u64 end_coord = static_cast(offset) + extent; + const u64 end_coord = u64(offset) + extent; if (end_coord > limit) { - extent = limit - static_cast(offset); + extent = limit - u32(offset); } }; @@ -464,30 +461,22 @@ void RasterizerVulkan::Clear(u32 layer_count) { const u32 color_attachment = regs.clear_surface.RT; if (use_color && framebuffer->HasAspectColorBit(color_attachment)) { - const auto format = - VideoCore::Surface::PixelFormatFromRenderTargetFormat(regs.rt[color_attachment].format); + const auto format = VideoCore::Surface::PixelFormatFromRenderTargetFormat(regs.rt[color_attachment].format); bool is_integer = IsPixelFormatInteger(format); bool is_signed = IsPixelFormatSignedInteger(format); size_t int_size = PixelComponentSizeBitsInteger(format); VkClearValue clear_value{}; if (!is_integer) { - std::memcpy(clear_value.color.float32, regs.clear_color.data(), - regs.clear_color.size() * sizeof(f32)); + std::memcpy(clear_value.color.float32, regs.clear_color.data(), regs.clear_color.size() * sizeof(f32)); } else if (!is_signed) { - for (size_t i = 0; i < 4; i++) { - clear_value.color.uint32[i] = static_cast( - static_cast(static_cast(int_size) << 1U) * regs.clear_color[i]); - } + for (size_t i = 0; i < 4; i++) + clear_value.color.uint32[i] = u32(f32(u64(int_size) << 1U) * regs.clear_color[i]); } else { - for (size_t i = 0; i < 4; i++) { - clear_value.color.int32[i] = - static_cast(static_cast(static_cast(int_size - 1) << 1) * - (regs.clear_color[i] - 0.5f)); - } + for (size_t i = 0; i < 4; i++) + clear_value.color.int32[i] = s32(f32(s64(int_size - 1) << 1) * (regs.clear_color[i] - 0.5f)); } - if (regs.clear_surface.R && regs.clear_surface.G && regs.clear_surface.B && - regs.clear_surface.A) { + if (regs.clear_surface.R && regs.clear_surface.G && regs.clear_surface.B && regs.clear_surface.A) { scheduler.Record([color_attachment, clear_value, clear_rect](vk::CommandBuffer cmdbuf) { const VkClearAttachment attachment{ .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, @@ -497,14 +486,11 @@ void RasterizerVulkan::Clear(u32 layer_count) { cmdbuf.ClearAttachments(attachment, clear_rect); }); } else { - u8 color_mask = static_cast(regs.clear_surface.R | regs.clear_surface.G << 1 | - regs.clear_surface.B << 2 | regs.clear_surface.A << 3); + u8 color_mask = u8(regs.clear_surface.R | regs.clear_surface.G << 1 | regs.clear_surface.B << 2 | regs.clear_surface.A << 3); Region2D dst_region = { Offset2D{.x = clear_rect.rect.offset.x, .y = clear_rect.rect.offset.y}, - Offset2D{.x = clear_rect.rect.offset.x + - static_cast(clear_rect.rect.extent.width), - .y = clear_rect.rect.offset.y + - static_cast(clear_rect.rect.extent.height)}}; + Offset2D{.x = clear_rect.rect.offset.x + s32(clear_rect.rect.extent.width), + .y = clear_rect.rect.offset.y + s32(clear_rect.rect.extent.height)}}; blit_image.ClearColor(framebuffer, color_mask, regs.clear_color, dst_region); } } @@ -527,11 +513,10 @@ void RasterizerVulkan::Clear(u32 layer_count) { regs.stencil_front_mask != 0) { Region2D dst_region = { Offset2D{.x = clear_rect.rect.offset.x, .y = clear_rect.rect.offset.y}, - Offset2D{.x = clear_rect.rect.offset.x + static_cast(clear_rect.rect.extent.width), - .y = clear_rect.rect.offset.y + - static_cast(clear_rect.rect.extent.height)}}; + Offset2D{.x = clear_rect.rect.offset.x + s32(clear_rect.rect.extent.width), + .y = clear_rect.rect.offset.y + s32(clear_rect.rect.extent.height)}}; blit_image.ClearDepthStencil(framebuffer, use_depth, regs.clear_depth, - static_cast(regs.stencil_front_mask), regs.clear_stencil, + u8(regs.stencil_front_mask), regs.clear_stencil, regs.stencil_front_func_mask, dst_region); } else { scheduler.Record([clear_depth = regs.clear_depth, clear_stencil = regs.clear_stencil, diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index cff7a73903..c930c809d1 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -860,8 +860,7 @@ TextureCacheRuntime::TextureCacheRuntime(const Device& device_, Scheduler& sched compute_pass_descriptor_queue, memory_allocator); } if (device.IsStorageImageMultisampleSupported()) { - msaa_copy_pass = std::make_unique( - device, scheduler, descriptor_pool, staging_buffer_pool, compute_pass_descriptor_queue); + msaa_copy_pass.emplace(device, scheduler, descriptor_pool, staging_buffer_pool, compute_pass_descriptor_queue); } if (!device.IsKhrImageFormatListSupported()) { return; @@ -1675,10 +1674,10 @@ void Image::UploadMemory(VkBuffer buffer, VkDeviceSize offset, // CHANGE: Gate the MSAA path more strictly and only use it for color, when the pass and device // support are available. Avoid running the MSAA path when prerequisites aren't met, // preventing validation and runtime issues. - const bool wants_msaa_upload = info.num_samples > 1 && - (aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT) != 0 && - runtime->CanUploadMSAA() && runtime->msaa_copy_pass != nullptr && - runtime->device.IsStorageImageMultisampleSupported(); + const bool wants_msaa_upload = info.num_samples > 1 + && (aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT) != 0 + && runtime->CanUploadMSAA() && runtime->msaa_copy_pass.has_value() + && runtime->device.IsStorageImageMultisampleSupported(); if (wants_msaa_upload) { // Create a temporary non-MSAA image to upload the data first @@ -2047,8 +2046,7 @@ bool Image::BlitScaleHelper(bool scale_up) { const u32 scaled_width = resolution.ScaleUp(info.size.width); const u32 scaled_height = is_2d ? resolution.ScaleUp(info.size.height) : info.size.height; std::unique_ptr& blit_view = scale_up ? scale_view : normal_view; - std::unique_ptr& blit_framebuffer = - scale_up ? scale_framebuffer : normal_framebuffer; + std::optional& blit_framebuffer = scale_up ? scale_framebuffer : normal_framebuffer; if (!blit_view) { const auto view_info = ImageViewInfo(ImageViewType::e2D, info.format); blit_view = std::make_unique(*runtime, view_info, NULL_IMAGE_ID, *this); @@ -2060,11 +2058,11 @@ bool Image::BlitScaleHelper(bool scale_up) { const u32 dst_height = scale_up ? scaled_height : info.size.height; const Region2D src_region{ .start = {0, 0}, - .end = {static_cast(src_width), static_cast(src_height)}, + .end = {s32(src_width), s32(src_height)}, }; const Region2D dst_region{ .start = {0, 0}, - .end = {static_cast(dst_width), static_cast(dst_height)}, + .end = {s32(dst_width), s32(dst_height)}, }; const VkExtent2D extent{ .width = (std::max)(scaled_width, info.size.width), @@ -2073,21 +2071,15 @@ bool Image::BlitScaleHelper(bool scale_up) { auto* view_ptr = blit_view.get(); if (aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT) { - if (!blit_framebuffer) { - blit_framebuffer = - std::make_unique(*runtime, view_ptr, nullptr, extent, scale_up); - } - - runtime->blit_image_helper.BlitColor(blit_framebuffer.get(), *blit_view, dst_region, - src_region, operation, BLIT_OPERATION); + if (!blit_framebuffer) + blit_framebuffer.emplace(*runtime, view_ptr, nullptr, extent, scale_up); + runtime->blit_image_helper.BlitColor(&*blit_framebuffer, *blit_view, + dst_region, src_region, operation, BLIT_OPERATION); } else if (aspect_mask == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { - if (!blit_framebuffer) { - blit_framebuffer = - std::make_unique(*runtime, nullptr, view_ptr, extent, scale_up); - } - runtime->blit_image_helper.BlitDepthStencil(blit_framebuffer.get(), *blit_view, - dst_region, src_region, operation, - BLIT_OPERATION); + if (!blit_framebuffer) + blit_framebuffer.emplace(*runtime, nullptr, view_ptr, extent, scale_up); + runtime->blit_image_helper.BlitDepthStencil(&*blit_framebuffer, *blit_view, + dst_region, src_region, operation, BLIT_OPERATION); } else { // TODO: Use helper blits where applicable flags &= ~ImageFlagBits::Rescaled; @@ -2200,9 +2192,9 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI } } -ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewInfo& info, - ImageId image_id_, Image& image, const SlotVector& slot_imgs) - : ImageView{runtime, info, image_id_, image} { +ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewInfo& info, ImageId image_id_, Image& image, const SlotVector& slot_imgs) + : ImageView{runtime, info, image_id_, image} +{ slot_images = &slot_imgs; } @@ -2267,33 +2259,25 @@ VkImageView ImageView::ColorView() { VkImageView ImageView::StorageView(Shader::TextureType texture_type, Shader::ImageFormat image_format) { - if (!image_handle) { - return VK_NULL_HANDLE; - } - if (image_format == Shader::ImageFormat::Typeless) { - return Handle(texture_type); - } - const bool is_signed{image_format == Shader::ImageFormat::R8_SINT || - image_format == Shader::ImageFormat::R16_SINT}; - if (!storage_views) { - storage_views = std::make_unique(); - } - auto& views{is_signed ? storage_views->signeds : storage_views->unsigneds}; - auto& view{views[static_cast(texture_type)]}; - if (view) { + if (image_handle) { + if (image_format == Shader::ImageFormat::Typeless) { + return Handle(texture_type); + } + const bool is_signed = image_format == Shader::ImageFormat::R8_SINT + || image_format == Shader::ImageFormat::R16_SINT; + if (!storage_views) + storage_views = std::make_optional(); + auto& views{is_signed ? storage_views->signeds : storage_views->unsigneds}; + auto& view{views[size_t(texture_type)]}; + if (!view) + view = MakeView(Format(image_format), VK_IMAGE_ASPECT_COLOR_BIT); return *view; } - view = MakeView(Format(image_format), VK_IMAGE_ASPECT_COLOR_BIT); - return *view; + return VK_NULL_HANDLE; } bool ImageView::IsRescaled() const noexcept { - if (!slot_images) { - return false; - } - const auto& slots = *slot_images; - const auto& src_image = slots[image_id]; - return src_image.IsRescaled(); + return (*slot_images)[image_id].IsRescaled(); } vk::ImageView ImageView::MakeView(VkFormat vk_format, VkImageAspectFlags aspect_mask) { diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h index dcc835f05e..6cc87d8c28 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.h +++ b/src/video_core/renderer_vulkan/vk_texture_cache.h @@ -133,7 +133,7 @@ public: vk::Buffer swizzle_table_buffer; VkDeviceSize swizzle_table_size = 0; - std::unique_ptr msaa_copy_pass; + std::optional msaa_copy_pass; const Settings::ResolutionScalingInfo& resolution; std::array, VideoCore::Surface::MaxPixelFormat> view_formats; @@ -141,6 +141,110 @@ public: std::array buffers{}; }; +class Sampler { +public: + explicit Sampler(TextureCacheRuntime&, const Tegra::Texture::TSCEntry&); + + [[nodiscard]] VkSampler Handle() const noexcept { + return *sampler; + } + + [[nodiscard]] VkSampler HandleWithDefaultAnisotropy() const noexcept { + return *sampler_default_anisotropy; + } + + [[nodiscard]] bool HasAddedAnisotropy() const noexcept { + return static_cast(sampler_default_anisotropy); + } + +private: + vk::Sampler sampler; + vk::Sampler sampler_default_anisotropy; +}; + +class Framebuffer { +public: + explicit Framebuffer(TextureCacheRuntime& runtime, std::span color_buffers, + ImageView* depth_buffer, const VideoCommon::RenderTargets& key); + + explicit Framebuffer(TextureCacheRuntime& runtime, ImageView* color_buffer, + ImageView* depth_buffer, VkExtent2D extent, bool is_rescaled); + + ~Framebuffer(); + + Framebuffer(const Framebuffer&) = delete; + Framebuffer& operator=(const Framebuffer&) = delete; + + Framebuffer(Framebuffer&&) = default; + Framebuffer& operator=(Framebuffer&&) = default; + + void CreateFramebuffer(TextureCacheRuntime& runtime, + std::span color_buffers, ImageView* depth_buffer, + bool is_rescaled = false); + + [[nodiscard]] VkFramebuffer Handle() const noexcept { + return *framebuffer; + } + + [[nodiscard]] VkRenderPass RenderPass() const noexcept { + return renderpass; + } + + [[nodiscard]] VkExtent2D RenderArea() const noexcept { + return render_area; + } + + [[nodiscard]] VkSampleCountFlagBits Samples() const noexcept { + return samples; + } + + [[nodiscard]] u32 NumColorBuffers() const noexcept { + return num_color_buffers; + } + + [[nodiscard]] u32 NumImages() const noexcept { + return num_images; + } + + [[nodiscard]] const std::array& Images() const noexcept { + return images; + } + + [[nodiscard]] const std::array& ImageRanges() const noexcept { + return image_ranges; + } + + [[nodiscard]] bool HasAspectColorBit(size_t index) const noexcept { + return (image_ranges.at(rt_map[index]).aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) != 0; + } + + [[nodiscard]] bool HasAspectDepthBit() const noexcept { + return has_depth; + } + + [[nodiscard]] bool HasAspectStencilBit() const noexcept { + return has_stencil; + } + + [[nodiscard]] bool IsRescaled() const noexcept { + return is_rescaled; + } + +private: + vk::Framebuffer framebuffer; + VkRenderPass renderpass{}; + VkExtent2D render_area{}; + VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT; + u32 num_color_buffers = 0; + u32 num_images = 0; + std::array images{}; + std::array image_ranges{}; + std::array rt_map{}; + bool has_depth{}; + bool has_stencil{}; + bool is_rescaled{}; +}; + class Image : public VideoCommon::ImageBase { public: explicit Image(TextureCacheRuntime&, const VideoCommon::ImageInfo& info, GPUVAddr gpu_addr, @@ -331,89 +435,6 @@ private: vk::Sampler sampler_default_anisotropy; }; -class Framebuffer { -public: - explicit Framebuffer(TextureCacheRuntime& runtime, std::span color_buffers, - ImageView* depth_buffer, const VideoCommon::RenderTargets& key); - - explicit Framebuffer(TextureCacheRuntime& runtime, ImageView* color_buffer, - ImageView* depth_buffer, VkExtent2D extent, bool is_rescaled); - - ~Framebuffer(); - - Framebuffer(const Framebuffer&) = delete; - Framebuffer& operator=(const Framebuffer&) = delete; - - Framebuffer(Framebuffer&&) = default; - Framebuffer& operator=(Framebuffer&&) = default; - - void CreateFramebuffer(TextureCacheRuntime& runtime, - std::span color_buffers, ImageView* depth_buffer, - bool is_rescaled = false); - - [[nodiscard]] VkFramebuffer Handle() const noexcept { - return *framebuffer; - } - - [[nodiscard]] VkRenderPass RenderPass() const noexcept { - return renderpass; - } - - [[nodiscard]] VkExtent2D RenderArea() const noexcept { - return render_area; - } - - [[nodiscard]] VkSampleCountFlagBits Samples() const noexcept { - return samples; - } - - [[nodiscard]] u32 NumColorBuffers() const noexcept { - return num_color_buffers; - } - - [[nodiscard]] u32 NumImages() const noexcept { - return num_images; - } - - [[nodiscard]] const std::array& Images() const noexcept { - return images; - } - - [[nodiscard]] const std::array& ImageRanges() const noexcept { - return image_ranges; - } - - [[nodiscard]] bool HasAspectColorBit(size_t index) const noexcept { - return (image_ranges.at(rt_map[index]).aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) != 0; - } - - [[nodiscard]] bool HasAspectDepthBit() const noexcept { - return has_depth; - } - - [[nodiscard]] bool HasAspectStencilBit() const noexcept { - return has_stencil; - } - - [[nodiscard]] bool IsRescaled() const noexcept { - return is_rescaled; - } - -private: - vk::Framebuffer framebuffer; - VkRenderPass renderpass{}; - VkExtent2D render_area{}; - VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT; - u32 num_color_buffers = 0; - u32 num_images = 0; - std::array images{}; - std::array image_ranges{}; - std::array rt_map{}; - bool has_depth{}; - bool has_stencil{}; - bool is_rescaled{}; -}; - struct TextureCacheParams { static constexpr bool ENABLE_VALIDATION = true; static constexpr bool FRAMEBUFFER_BLITS = false; diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 425c8e23de..53fb57317f 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -596,10 +596,10 @@ FramebufferId TextureCache

::GetFramebufferId(const RenderTargets& key) { return framebuffer_id; } std::array color_buffers; - std::ranges::transform(key.color_buffer_ids, color_buffers.begin(), - [this](ImageViewId id) { return id ? &slot_image_views[id] : nullptr; }); - ImageView* const depth_buffer = - key.depth_buffer_id ? &slot_image_views[key.depth_buffer_id] : nullptr; + std::ranges::transform(key.color_buffer_ids, color_buffers.begin(), [this](ImageViewId id) { + return id ? &slot_image_views[id] : nullptr; + }); + ImageView* const depth_buffer = key.depth_buffer_id ? &slot_image_views[key.depth_buffer_id] : nullptr; framebuffer_id = slot_framebuffers.insert(runtime, color_buffers, depth_buffer, key); return framebuffer_id; }