diff options
Diffstat (limited to 'src/video_core')
19 files changed, 79 insertions, 36 deletions
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 6d3d933c5..ed7a5b27e 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -35,7 +35,7 @@ BufferCache<P>::BufferCache(Tegra::MaxwellDeviceMemoryManager& device_memory_, R const s64 min_spacing_critical = device_local_memory - 512_MiB; const s64 mem_threshold = std::min(device_local_memory, TARGET_THRESHOLD); const s64 min_vacancy_expected = (6 * mem_threshold) / 10; - const s64 min_vacancy_critical = (3 * mem_threshold) / 10; + const s64 min_vacancy_critical = (2 * mem_threshold) / 10; minimum_memory = static_cast<u64>( std::max(std::min(device_local_memory - min_vacancy_expected, min_spacing_expected), DEFAULT_EXPECTED_MEMORY)); @@ -1130,7 +1130,7 @@ void BufferCache<P>::UpdateVertexBuffer(u32 index) { channel_state->vertex_buffers[index] = NULL_BINDING; return; } - if (!gpu_memory->IsWithinGPUAddressRange(gpu_addr_end)) { + if (!gpu_memory->IsWithinGPUAddressRange(gpu_addr_end) || size >= 64_MiB) { size = static_cast<u32>(gpu_memory->MaxContinuousRange(gpu_addr_begin, size)); } const BufferId buffer_id = FindBuffer(*device_addr, size); diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index a94e1f043..0d47b032c 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -291,7 +291,9 @@ u32 Maxwell3D::ProcessShadowRam(u32 method, u32 argument) { } void Maxwell3D::ConsumeSinkImpl() { - SCOPE_EXIT({ method_sink.clear(); }); + SCOPE_EXIT { + method_sink.clear(); + }; const auto control = shadow_state.shadow_ram_control; if (control == Regs::ShadowRamControl::Track || control == Regs::ShadowRamControl::TrackWithFilter) { diff --git a/src/video_core/fence_manager.h b/src/video_core/fence_manager.h index c3eda6893..2135f1f2d 100644 --- a/src/video_core/fence_manager.h +++ b/src/video_core/fence_manager.h @@ -197,7 +197,9 @@ private: MicroProfileOnThreadCreate(name.c_str()); // Cleanup - SCOPE_EXIT({ MicroProfileOnThreadExit(); }); + SCOPE_EXIT { + MicroProfileOnThreadExit(); + }; Common::SetCurrentThreadName(name.c_str()); Common::SetCurrentThreadPriority(Common::ThreadPriority::High); diff --git a/src/video_core/gpu_thread.cpp b/src/video_core/gpu_thread.cpp index 58d8110b8..477e11457 100644 --- a/src/video_core/gpu_thread.cpp +++ b/src/video_core/gpu_thread.cpp @@ -22,7 +22,9 @@ static void RunThread(std::stop_token stop_token, Core::System& system, Tegra::Control::Scheduler& scheduler, SynchState& state) { std::string name = "GPU"; MicroProfileOnThreadCreate(name.c_str()); - SCOPE_EXIT({ MicroProfileOnThreadExit(); }); + SCOPE_EXIT { + MicroProfileOnThreadExit(); + }; Common::SetCurrentThreadName(name.c_str()); Common::SetCurrentThreadPriority(Common::ThreadPriority::Critical); diff --git a/src/video_core/host1x/ffmpeg/ffmpeg.cpp b/src/video_core/host1x/ffmpeg/ffmpeg.cpp index 96686da59..1003cd38d 100644 --- a/src/video_core/host1x/ffmpeg/ffmpeg.cpp +++ b/src/video_core/host1x/ffmpeg/ffmpeg.cpp @@ -273,10 +273,10 @@ DeinterlaceFilter::DeinterlaceFilter(const Frame& frame) { const AVFilter* buffer_sink = avfilter_get_by_name("buffersink"); AVFilterInOut* inputs = avfilter_inout_alloc(); AVFilterInOut* outputs = avfilter_inout_alloc(); - SCOPE_EXIT({ + SCOPE_EXIT { avfilter_inout_free(&inputs); avfilter_inout_free(&outputs); - }); + }; // Don't know how to get the accurate time_base but it doesn't matter for yadif filter // so just use 1/1 to make buffer filter happy diff --git a/src/video_core/macro/macro_hle.cpp b/src/video_core/macro/macro_hle.cpp index 46e853e04..fb529f88b 100644 --- a/src/video_core/macro/macro_hle.cpp +++ b/src/video_core/macro/macro_hle.cpp @@ -92,12 +92,12 @@ public: private: void Fallback(const std::vector<u32>& parameters) { - SCOPE_EXIT({ + SCOPE_EXIT { if (extended) { maxwell3d.engine_state = Maxwell3D::EngineHint::None; maxwell3d.replace_table.clear(); } - }); + }; maxwell3d.RefreshParameters(); const u32 instance_count = (maxwell3d.GetRegisterValue(0xD1B) & parameters[2]); @@ -281,12 +281,12 @@ public: private: void Fallback(const std::vector<u32>& parameters) { - SCOPE_EXIT({ + SCOPE_EXIT { // Clean everything. maxwell3d.regs.vertex_id_base = 0x0; maxwell3d.engine_state = Maxwell3D::EngineHint::None; maxwell3d.replace_table.clear(); - }); + }; maxwell3d.RefreshParameters(); const u32 start_indirect = parameters[0]; const u32 end_indirect = parameters[1]; diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index b42fb110c..16af8e6bd 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -230,7 +230,9 @@ template <typename Func> void RasterizerOpenGL::PrepareDraw(bool is_indexed, Func&& draw_func) { MICROPROFILE_SCOPE(OpenGL_Drawing); - SCOPE_EXIT({ gpu.TickWork(); }); + SCOPE_EXIT { + gpu.TickWork(); + }; gpu_memory->FlushCaching(); GraphicsPipeline* const pipeline{shader_cache.CurrentGraphicsPipeline()}; @@ -355,7 +357,9 @@ void RasterizerOpenGL::DrawIndirect() { void RasterizerOpenGL::DrawTexture() { MICROPROFILE_SCOPE(OpenGL_Drawing); - SCOPE_EXIT({ gpu.TickWork(); }); + SCOPE_EXIT { + gpu.TickWork(); + }; texture_cache.SynchronizeGraphicsDescriptors(); texture_cache.UpdateRenderTargets(false); diff --git a/src/video_core/renderer_vulkan/present/layer.cpp b/src/video_core/renderer_vulkan/present/layer.cpp index 3847a9a13..4e41afe5b 100644 --- a/src/video_core/renderer_vulkan/present/layer.cpp +++ b/src/video_core/renderer_vulkan/present/layer.cpp @@ -82,7 +82,9 @@ void Layer::ConfigureDraw(PresentPushConstants* out_push_constants, // Finish any pending renderpass scheduler.RequestOutsideRenderPassOperationContext(); scheduler.Wait(resource_ticks[image_index]); - SCOPE_EXIT({ resource_ticks[image_index] = scheduler.CurrentTick(); }); + SCOPE_EXIT { + resource_ticks[image_index] = scheduler.CurrentTick(); + }; if (!use_accelerated) { UpdateRawImage(framebuffer, image_index); diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index d50417116..c553f5b3d 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp @@ -144,7 +144,9 @@ void RendererVulkan::Composite(std::span<const Tegra::FramebufferConfig> framebu return; } - SCOPE_EXIT({ render_window.OnFrameDisplayed(); }); + SCOPE_EXIT { + render_window.OnFrameDisplayed(); + }; RenderAppletCaptureLayer(framebuffers); diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 20f7a9702..d34b585d6 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -352,6 +352,7 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_, .support_native_ndc = device.IsExtDepthClipControlSupported(), .support_scaled_attributes = !device.MustEmulateScaledFormats(), .support_multi_viewport = device.SupportsMultiViewport(), + .support_geometry_streams = device.AreTransformFeedbackGeometryStreamsSupported(), .warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyBiggerThanGuest(), diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index aa0a027bb..74f9f099e 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -196,7 +196,9 @@ template <typename Func> void RasterizerVulkan::PrepareDraw(bool is_indexed, Func&& draw_func) { MICROPROFILE_SCOPE(Vulkan_Drawing); - SCOPE_EXIT({ gpu.TickWork(); }); + SCOPE_EXIT { + gpu.TickWork(); + }; FlushWork(); gpu_memory->FlushCaching(); @@ -288,7 +290,9 @@ void RasterizerVulkan::DrawIndirect() { void RasterizerVulkan::DrawTexture() { MICROPROFILE_SCOPE(Vulkan_Drawing); - SCOPE_EXIT({ gpu.TickWork(); }); + SCOPE_EXIT { + gpu.TickWork(); + }; FlushWork(); query_cache.NotifySegment(true); diff --git a/src/video_core/surface.cpp b/src/video_core/surface.cpp index 5b3c7aa5a..9055b1b92 100644 --- a/src/video_core/surface.cpp +++ b/src/video_core/surface.cpp @@ -3,6 +3,7 @@ #include "common/common_types.h" #include "common/math_util.h" +#include "common/settings.h" #include "video_core/surface.h" namespace VideoCore::Surface { @@ -400,11 +401,20 @@ std::pair<u32, u32> GetASTCBlockSize(PixelFormat format) { return {DefaultBlockWidth(format), DefaultBlockHeight(format)}; } -u64 EstimatedDecompressedSize(u64 base_size, PixelFormat format) { +u64 TranscodedAstcSize(u64 base_size, PixelFormat format) { constexpr u64 RGBA8_PIXEL_SIZE = 4; const u64 base_block_size = static_cast<u64>(DefaultBlockWidth(format)) * static_cast<u64>(DefaultBlockHeight(format)) * RGBA8_PIXEL_SIZE; - return (base_size * base_block_size) / BytesPerBlock(format); + const u64 uncompressed_size = (base_size * base_block_size) / BytesPerBlock(format); + + switch (Settings::values.astc_recompression.GetValue()) { + case Settings::AstcRecompression::Bc1: + return uncompressed_size / 8; + case Settings::AstcRecompression::Bc3: + return uncompressed_size / 4; + default: + return uncompressed_size; + } } } // namespace VideoCore::Surface diff --git a/src/video_core/surface.h b/src/video_core/surface.h index a5e8e2f62..ec9cd2fbf 100644 --- a/src/video_core/surface.h +++ b/src/video_core/surface.h @@ -517,6 +517,6 @@ size_t PixelComponentSizeBitsInteger(PixelFormat format); std::pair<u32, u32> GetASTCBlockSize(PixelFormat format); -u64 EstimatedDecompressedSize(u64 base_size, PixelFormat format); +u64 TranscodedAstcSize(u64 base_size, PixelFormat format); } // namespace VideoCore::Surface diff --git a/src/video_core/texture_cache/image_info.cpp b/src/video_core/texture_cache/image_info.cpp index b72788c6d..9444becce 100644 --- a/src/video_core/texture_cache/image_info.cpp +++ b/src/video_core/texture_cache/image_info.cpp @@ -42,6 +42,7 @@ ImageInfo::ImageInfo(const TICEntry& config) noexcept { }; } rescaleable = false; + is_sparse = config.is_sparse != 0; tile_width_spacing = config.tile_width_spacing; if (config.texture_type != TextureType::Texture2D && config.texture_type != TextureType::Texture2DNoMipmap) { diff --git a/src/video_core/texture_cache/image_info.h b/src/video_core/texture_cache/image_info.h index 8a4cb0cbd..eb490a642 100644 --- a/src/video_core/texture_cache/image_info.h +++ b/src/video_core/texture_cache/image_info.h @@ -41,6 +41,7 @@ struct ImageInfo { bool downscaleable = false; bool forced_flushed = false; bool dma_downloaded = false; + bool is_sparse = false; }; } // namespace VideoCommon diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 3a1cc060e..53b4876f2 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -55,7 +55,7 @@ TextureCache<P>::TextureCache(Runtime& runtime_, Tegra::MaxwellDeviceMemoryManag const s64 min_spacing_critical = device_local_memory - 512_MiB; const s64 mem_threshold = std::min(device_local_memory, TARGET_THRESHOLD); const s64 min_vacancy_expected = (6 * mem_threshold) / 10; - const s64 min_vacancy_critical = (3 * mem_threshold) / 10; + const s64 min_vacancy_critical = (2 * mem_threshold) / 10; expected_memory = static_cast<u64>( std::max(std::min(device_local_memory - min_vacancy_expected, min_spacing_expected), DEFAULT_EXPECTED_MEMORY)); @@ -600,17 +600,17 @@ void TextureCache<P>::UnmapGPUMemory(size_t as_id, GPUVAddr gpu_addr, size_t siz [&](ImageId id, Image&) { deleted_images.push_back(id); }); for (const ImageId id : deleted_images) { Image& image = slot_images[id]; - if (True(image.flags & ImageFlagBits::CpuModified)) { - continue; + if (False(image.flags & ImageFlagBits::CpuModified)) { + image.flags |= ImageFlagBits::CpuModified; + if (True(image.flags & ImageFlagBits::Tracked)) { + UntrackImage(image, id); + } } - image.flags |= ImageFlagBits::CpuModified; + if (True(image.flags & ImageFlagBits::Remapped)) { continue; } image.flags |= ImageFlagBits::Remapped; - if (True(image.flags & ImageFlagBits::Tracked)) { - UntrackImage(image, id); - } } } @@ -1469,7 +1469,8 @@ ImageId TextureCache<P>::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, DA const ImageId new_image_id = slot_images.insert(runtime, new_info, gpu_addr, cpu_addr); Image& new_image = slot_images[new_image_id]; - if (!gpu_memory->IsContinuousRange(new_image.gpu_addr, new_image.guest_size_bytes)) { + if (!gpu_memory->IsContinuousRange(new_image.gpu_addr, new_image.guest_size_bytes) && + new_info.is_sparse) { new_image.flags |= ImageFlagBits::Sparse; } @@ -1978,7 +1979,7 @@ void TextureCache<P>::RegisterImage(ImageId image_id) { if ((IsPixelFormatASTC(image.info.format) && True(image.flags & ImageFlagBits::AcceleratedUpload)) || True(image.flags & ImageFlagBits::Converted)) { - tentative_size = EstimatedDecompressedSize(tentative_size, image.info.format); + tentative_size = TranscodedAstcSize(tentative_size, image.info.format); } total_used_memory += Common::AlignUp(tentative_size, 1024); image.lru_index = lru_cache.Insert(image_id, frame_tick); @@ -2148,7 +2149,7 @@ void TextureCache<P>::DeleteImage(ImageId image_id, bool immediate_delete) { if ((IsPixelFormatASTC(image.info.format) && True(image.flags & ImageFlagBits::AcceleratedUpload)) || True(image.flags & ImageFlagBits::Converted)) { - tentative_size = EstimatedDecompressedSize(tentative_size, image.info.format); + tentative_size = TranscodedAstcSize(tentative_size, image.info.format); } total_used_memory -= Common::AlignUp(tentative_size, 1024); const GPUVAddr gpu_addr = image.gpu_addr; diff --git a/src/video_core/vulkan_common/nsight_aftermath_tracker.cpp b/src/video_core/vulkan_common/nsight_aftermath_tracker.cpp index 5fa0d9620..f41c3e506 100644 --- a/src/video_core/vulkan_common/nsight_aftermath_tracker.cpp +++ b/src/video_core/vulkan_common/nsight_aftermath_tracker.cpp @@ -116,7 +116,9 @@ void NsightAftermathTracker::OnGpuCrashDumpCallback(const void* gpu_crash_dump, LOG_ERROR(Render_Vulkan, "Failed to create decoder"); return; } - SCOPE_EXIT({ GFSDK_Aftermath_GpuCrashDump_DestroyDecoder(decoder); }); + SCOPE_EXIT { + GFSDK_Aftermath_GpuCrashDump_DestroyDecoder(decoder); + }; u32 json_size = 0; if (!GFSDK_Aftermath_SUCCEED(GFSDK_Aftermath_GpuCrashDump_GenerateJSON( diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index d7216d349..b94924a58 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -1297,10 +1297,6 @@ u64 Device::GetDeviceMemoryUsage() const { } void Device::CollectPhysicalMemoryInfo() { - // Account for resolution scaling in memory limits - const size_t normal_memory = 6_GiB; - const size_t scaler_memory = 1_GiB * Settings::values.resolution_info.ScaleUp(1); - // Calculate limits using memory budget VkPhysicalDeviceMemoryBudgetPropertiesEXT budget{}; budget.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT; @@ -1331,7 +1327,15 @@ void Device::CollectPhysicalMemoryInfo() { if (!is_integrated) { const u64 reserve_memory = std::min<u64>(device_access_memory / 8, 1_GiB); device_access_memory -= reserve_memory; - device_access_memory = std::min<u64>(device_access_memory, normal_memory + scaler_memory); + + if (Settings::values.vram_usage_mode.GetValue() != Settings::VramUsageMode::Aggressive) { + // Account for resolution scaling in memory limits + const size_t normal_memory = 6_GiB; + const size_t scaler_memory = 1_GiB * Settings::values.resolution_info.ScaleUp(1); + device_access_memory = + std::min<u64>(device_access_memory, normal_memory + scaler_memory); + } + return; } const s64 available_memory = static_cast<s64>(device_access_memory - device_initial_usage); diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index a2ec26697..e3abe8ddf 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h @@ -499,6 +499,11 @@ public: return extensions.transform_feedback; } + /// Returns true if the device supports VK_EXT_transform_feedback properly. + bool AreTransformFeedbackGeometryStreamsSupported() const { + return features.transform_feedback.geometryStreams; + } + /// Returns true if the device supports VK_EXT_custom_border_color. bool IsExtCustomBorderColorSupported() const { return extensions.custom_border_color; |