From a7deacc21a275cea0ca67b79e189b3b7f5cf35be Mon Sep 17 00:00:00 2001 From: pineappleEA Date: Mon, 25 Oct 2021 16:18:43 +0200 Subject: [PATCH] early-access version 2160 --- README.md | 2 +- src/core/hle/kernel/k_scheduler.h | 5 +++ src/core/hle/kernel/svc.cpp | 17 ++++++++++ .../renderer_opengl/gl_resource_manager.cpp | 7 +++- .../renderer_opengl/gl_texture_cache.cpp | 14 ++------ src/video_core/texture_cache/image_base.h | 2 +- src/video_core/texture_cache/texture_cache.h | 33 +++++++++++-------- .../texture_cache/texture_cache_base.h | 5 +++ 8 files changed, 56 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index 34382240a..e757ffac3 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 2159. +This is the source code for early-access 2160. ## Legal Notice diff --git a/src/core/hle/kernel/k_scheduler.h b/src/core/hle/kernel/k_scheduler.h index c8ccc1ae4..7df288438 100755 --- a/src/core/hle/kernel/k_scheduler.h +++ b/src/core/hle/kernel/k_scheduler.h @@ -49,6 +49,11 @@ public: /// Gets the current running thread [[nodiscard]] KThread* GetCurrentThread() const; + /// Gets the idle thread + [[nodiscard]] KThread* GetIdleThread() const { + return idle_thread; + } + /// Returns true if the scheduler is idle [[nodiscard]] bool IsIdle() const { return GetCurrentThread() == idle_thread; diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index f98f24a60..7f38ade1c 100755 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -886,7 +886,24 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, Handle *result = out_ticks; return ResultSuccess; } + case GetInfoType::IdleTickCount: { + if (handle == 0) { + LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", + static_cast(handle)); + return ResultInvalidHandle; + } + if (info_sub_id != 0xFFFFFFFFFFFFFFFF && info_sub_id != system.CurrentCoreIndex()) { + LOG_ERROR(Kernel_SVC, "Core is not the current core, got {}", info_sub_id); + return ResultInvalidCombination; + } + + const auto& scheduler = *system.Kernel().CurrentScheduler(); + const auto* const idle_thread = scheduler.GetIdleThread(); + + *result = idle_thread->GetCpuTime(); + return ResultSuccess; + } default: LOG_ERROR(Kernel_SVC, "Unimplemented svcGetInfo id=0x{:016X}", info_id); return ResultInvalidEnumValue; diff --git a/src/video_core/renderer_opengl/gl_resource_manager.cpp b/src/video_core/renderer_opengl/gl_resource_manager.cpp index 70947838c..5e7101d28 100755 --- a/src/video_core/renderer_opengl/gl_resource_manager.cpp +++ b/src/video_core/renderer_opengl/gl_resource_manager.cpp @@ -166,7 +166,12 @@ void OGLFramebuffer::Create() { return; MICROPROFILE_SCOPE(OpenGL_ResourceCreation); - glCreateFramebuffers(1, &handle); + // Bind to READ_FRAMEBUFFER to stop Nvidia's driver from creating an EXT_framebuffer instead of + // a core framebuffer. EXT framebuffer attachments have to match in size and can be shared + // across contexts. yuzu doesn't share framebuffers across contexts and we need attachments with + // mismatching size, this is why core framebuffers are preferred. + glGenFramebuffers(1, &handle); + glBindFramebuffer(GL_READ_FRAMEBUFFER, handle); } void OGLFramebuffer::Release() { diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index 6841b5450..00610ea2c 100755 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp @@ -478,10 +478,6 @@ TextureCacheRuntime::TextureCacheRuntime(const Device& device_, ProgramManager& for (size_t i = 0; i < rescale_draw_fbos.size(); ++i) { rescale_draw_fbos[i].Create(); rescale_read_fbos[i].Create(); - - // Make sure the framebuffer is created without DSA - glBindFramebuffer(GL_READ_FRAMEBUFFER, rescale_draw_fbos[i].handle); - glBindFramebuffer(GL_READ_FRAMEBUFFER, rescale_read_fbos[i].handle); } } } @@ -1224,13 +1220,8 @@ Sampler::Sampler(TextureCacheRuntime& runtime, const TSCEntry& config) { Framebuffer::Framebuffer(TextureCacheRuntime& runtime, std::span color_buffers, ImageView* depth_buffer, const VideoCommon::RenderTargets& key) { - // Bind to READ_FRAMEBUFFER to stop Nvidia's driver from creating an EXT_framebuffer instead of - // a core framebuffer. EXT framebuffer attachments have to match in size and can be shared - // across contexts. yuzu doesn't share framebuffers across contexts and we need attachments with - // mismatching size, this is why core framebuffers are preferred. - GLuint handle; - glGenFramebuffers(1, &handle); - glBindFramebuffer(GL_READ_FRAMEBUFFER, handle); + framebuffer.Create(); + GLuint handle = framebuffer.handle; GLsizei num_buffers = 0; std::array gl_draw_buffers; @@ -1278,7 +1269,6 @@ Framebuffer::Framebuffer(TextureCacheRuntime& runtime, std::span(name.size()), name.data()); } - framebuffer.handle = handle; } void BGRCopyPass::CopyBGR(Image& dst_image, Image& src_image, diff --git a/src/video_core/texture_cache/image_base.h b/src/video_core/texture_cache/image_base.h index c960d807c..02c669766 100755 --- a/src/video_core/texture_cache/image_base.h +++ b/src/video_core/texture_cache/image_base.h @@ -77,7 +77,7 @@ struct ImageBase { void CheckBadOverlapState(); void CheckAliasState(); - bool HasScaled() { + bool HasScaled() const { return has_scaled; } diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 26ab857c9..c8031b695 100755 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -192,19 +192,8 @@ void TextureCache

::SynchronizeComputeDescriptors() { } template -void TextureCache

::UpdateRenderTargets(bool is_clear) { - using namespace VideoCommon::Dirty; +bool TextureCache

::RescaleRenderTargets(bool is_clear) { auto& flags = maxwell3d.dirty.flags; - if (!flags[Dirty::RenderTargets]) { - for (size_t index = 0; index < NUM_RT; ++index) { - ImageViewId& color_buffer_id = render_targets.color_buffer_ids[index]; - PrepareImageView(color_buffer_id, true, is_clear && IsFullClear(color_buffer_id)); - } - const ImageViewId depth_buffer_id = render_targets.depth_buffer_id; - PrepareImageView(depth_buffer_id, true, is_clear && IsFullClear(depth_buffer_id)); - return; - } - u32 scale_rating = 0; bool rescaled = false; std::array tmp_color_images{}; @@ -281,8 +270,6 @@ void TextureCache

::UpdateRenderTargets(bool is_clear) { scale_rating = 1; } } while (has_deleted_images); - // Rescale End - const auto set_rating = [this, scale_rating](ImageId image_id) { if (image_id != CORRUPT_ID) { Image& image = slot_images[image_id]; @@ -297,6 +284,24 @@ void TextureCache

::UpdateRenderTargets(bool is_clear) { } set_rating(tmp_depth_image); + return rescaled; +} + +template +void TextureCache

::UpdateRenderTargets(bool is_clear) { + using namespace VideoCommon::Dirty; + auto& flags = maxwell3d.dirty.flags; + if (!flags[Dirty::RenderTargets]) { + for (size_t index = 0; index < NUM_RT; ++index) { + ImageViewId& color_buffer_id = render_targets.color_buffer_ids[index]; + PrepareImageView(color_buffer_id, true, is_clear && IsFullClear(color_buffer_id)); + } + const ImageViewId depth_buffer_id = render_targets.depth_buffer_id; + PrepareImageView(depth_buffer_id, true, is_clear && IsFullClear(depth_buffer_id)); + return; + } + + const bool rescaled = RescaleRenderTargets(is_clear); if (is_rescaling != rescaled) { flags[Dirty::RescaleViewports] = true; flags[Dirty::RescaleScissors] = true; diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h index eea589269..643ad811c 100755 --- a/src/video_core/texture_cache/texture_cache_base.h +++ b/src/video_core/texture_cache/texture_cache_base.h @@ -119,6 +119,11 @@ public: /// Refresh the state for compute image view and sampler descriptors void SynchronizeComputeDescriptors(); + /// Updates the Render Targets if they can be rescaled + /// @param is_clear True when the render targets are being used for clears + /// @retval True if the Render Targets have been rescaled. + bool RescaleRenderTargets(bool is_clear); + /// Update bound render targets and upload memory if necessary /// @param is_clear True when the render targets are being used for clears void UpdateRenderTargets(bool is_clear);