early-access version 3605
This commit is contained in:
parent
b6b3e678ad
commit
1537f02c4c
14 changed files with 61 additions and 50 deletions
|
@ -1,7 +1,7 @@
|
||||||
yuzu emulator early access
|
yuzu emulator early access
|
||||||
=============
|
=============
|
||||||
|
|
||||||
This is the source code for early-access 3604.
|
This is the source code for early-access 3605.
|
||||||
|
|
||||||
## Legal Notice
|
## Legal Notice
|
||||||
|
|
||||||
|
|
|
@ -154,6 +154,11 @@ void AudioRenderer::ThreadFunc() {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case RenderMessage::AudioRenderer_Render: {
|
case RenderMessage::AudioRenderer_Render: {
|
||||||
|
if (system.IsShuttingDown()) [[unlikely]] {
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
||||||
|
mailbox->ADSPSendMessage(RenderMessage::AudioRenderer_RenderResponse);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
std::array<bool, MaxRendererSessions> buffers_reset{};
|
std::array<bool, MaxRendererSessions> buffers_reset{};
|
||||||
std::array<u64, MaxRendererSessions> render_times_taken{};
|
std::array<u64, MaxRendererSessions> render_times_taken{};
|
||||||
const auto start_time{system.CoreTiming().GetClockTicks()};
|
const auto start_time{system.CoreTiming().GetClockTicks()};
|
||||||
|
|
|
@ -27,7 +27,7 @@ bool SystemManager::InitializeUnsafe() {
|
||||||
if (!active) {
|
if (!active) {
|
||||||
if (adsp.Start()) {
|
if (adsp.Start()) {
|
||||||
active = true;
|
active = true;
|
||||||
thread = std::jthread([this](std::stop_token stop_token) { ThreadFunc(); });
|
thread = std::jthread([this](std::stop_token stop_token) { ThreadFunc(stop_token); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,8 +39,7 @@ void SystemManager::Stop() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
active = false;
|
active = false;
|
||||||
update.store(true);
|
thread.request_stop();
|
||||||
update.notify_all();
|
|
||||||
thread.join();
|
thread.join();
|
||||||
adsp.Stop();
|
adsp.Stop();
|
||||||
}
|
}
|
||||||
|
@ -85,12 +84,12 @@ bool SystemManager::Remove(System& system_) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SystemManager::ThreadFunc() {
|
void SystemManager::ThreadFunc(std::stop_token stop_token) {
|
||||||
static constexpr char name[]{"AudioRenderSystemManager"};
|
static constexpr char name[]{"AudioRenderSystemManager"};
|
||||||
MicroProfileOnThreadCreate(name);
|
MicroProfileOnThreadCreate(name);
|
||||||
Common::SetCurrentThreadName(name);
|
Common::SetCurrentThreadName(name);
|
||||||
Common::SetCurrentThreadPriority(Common::ThreadPriority::High);
|
Common::SetCurrentThreadPriority(Common::ThreadPriority::High);
|
||||||
while (active) {
|
while (active && !stop_token.stop_requested()) {
|
||||||
{
|
{
|
||||||
std::scoped_lock l{mutex1};
|
std::scoped_lock l{mutex1};
|
||||||
|
|
||||||
|
|
|
@ -66,13 +66,7 @@ private:
|
||||||
/**
|
/**
|
||||||
* Main thread responsible for command generation.
|
* Main thread responsible for command generation.
|
||||||
*/
|
*/
|
||||||
void ThreadFunc();
|
void ThreadFunc(std::stop_token stop_token);
|
||||||
|
|
||||||
enum class StreamState {
|
|
||||||
Filling,
|
|
||||||
Steady,
|
|
||||||
Draining,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Core system
|
/// Core system
|
||||||
Core::System& core;
|
Core::System& core;
|
||||||
|
@ -90,8 +84,6 @@ private:
|
||||||
ADSP::ADSP& adsp;
|
ADSP::ADSP& adsp;
|
||||||
/// AudioRenderer mailbox for communication
|
/// AudioRenderer mailbox for communication
|
||||||
ADSP::AudioRenderer_Mailbox* mailbox{};
|
ADSP::AudioRenderer_Mailbox* mailbox{};
|
||||||
/// Atomic for main thread to wait on
|
|
||||||
std::atomic<bool> update{};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AudioCore::AudioRenderer
|
} // namespace AudioCore::AudioRenderer
|
||||||
|
|
|
@ -270,8 +270,8 @@ u64 SinkStream::GetExpectedPlayedSampleCount() {
|
||||||
|
|
||||||
void SinkStream::WaitFreeSpace() {
|
void SinkStream::WaitFreeSpace() {
|
||||||
std::unique_lock lk{release_mutex};
|
std::unique_lock lk{release_mutex};
|
||||||
release_cv.wait(
|
release_cv.wait_for(lk, std::chrono::milliseconds(5),
|
||||||
lk, [this]() { return queued_buffers < max_queue_size || system.IsShuttingDown(); });
|
[this]() { return queued_buffers < max_queue_size; });
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AudioCore::Sink
|
} // namespace AudioCore::Sink
|
||||||
|
|
|
@ -144,7 +144,7 @@ public:
|
||||||
return state_tracker;
|
return state_tracker;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckFeedbackLoop(ImageView& image_view) const noexcept {
|
void BarrierFeedbackLoop() const noexcept {
|
||||||
// OpenGL does not require a barrier for attachment feedback loops.
|
// OpenGL does not require a barrier for attachment feedback loops.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -175,7 +175,6 @@ public:
|
||||||
std::array<f32, 4> words{};
|
std::array<f32, 4> words{};
|
||||||
};
|
};
|
||||||
|
|
||||||
template <bool CheckFeedbackLoop = false>
|
|
||||||
inline void PushImageDescriptors(TextureCache& texture_cache,
|
inline void PushImageDescriptors(TextureCache& texture_cache,
|
||||||
GuestDescriptorQueue& guest_descriptor_queue,
|
GuestDescriptorQueue& guest_descriptor_queue,
|
||||||
const Shader::Info& info, RescalingPushConstant& rescaling,
|
const Shader::Info& info, RescalingPushConstant& rescaling,
|
||||||
|
@ -193,9 +192,6 @@ inline void PushImageDescriptors(TextureCache& texture_cache,
|
||||||
const VkImageView vk_image_view{image_view.Handle(desc.type)};
|
const VkImageView vk_image_view{image_view.Handle(desc.type)};
|
||||||
guest_descriptor_queue.AddSampledImage(vk_image_view, sampler);
|
guest_descriptor_queue.AddSampledImage(vk_image_view, sampler);
|
||||||
rescaling.PushTexture(texture_cache.IsRescaling(image_view));
|
rescaling.PushTexture(texture_cache.IsRescaling(image_view));
|
||||||
if constexpr (CheckFeedbackLoop) {
|
|
||||||
texture_cache.CheckFeedbackLoop(image_view);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const auto& desc : info.image_descriptors) {
|
for (const auto& desc : info.image_descriptors) {
|
||||||
|
@ -207,9 +203,6 @@ inline void PushImageDescriptors(TextureCache& texture_cache,
|
||||||
const VkImageView vk_image_view{image_view.StorageView(desc.type, desc.format)};
|
const VkImageView vk_image_view{image_view.StorageView(desc.type, desc.format)};
|
||||||
guest_descriptor_queue.AddImage(vk_image_view);
|
guest_descriptor_queue.AddImage(vk_image_view);
|
||||||
rescaling.PushImage(texture_cache.IsRescaling(image_view));
|
rescaling.PushImage(texture_cache.IsRescaling(image_view));
|
||||||
if constexpr (CheckFeedbackLoop) {
|
|
||||||
texture_cache.CheckFeedbackLoop(image_view);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -457,8 +457,8 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
|
||||||
const VideoCommon::ImageViewInOut* views_it{views.data()};
|
const VideoCommon::ImageViewInOut* views_it{views.data()};
|
||||||
const auto prepare_stage{[&](size_t stage) LAMBDA_FORCEINLINE {
|
const auto prepare_stage{[&](size_t stage) LAMBDA_FORCEINLINE {
|
||||||
buffer_cache.BindHostStageBuffers(stage);
|
buffer_cache.BindHostStageBuffers(stage);
|
||||||
PushImageDescriptors<true>(texture_cache, guest_descriptor_queue, stage_infos[stage],
|
PushImageDescriptors(texture_cache, guest_descriptor_queue, stage_infos[stage], rescaling,
|
||||||
rescaling, samplers_it, views_it);
|
samplers_it, views_it);
|
||||||
const auto& info{stage_infos[0]};
|
const auto& info{stage_infos[0]};
|
||||||
if (info.uses_render_area) {
|
if (info.uses_render_area) {
|
||||||
render_area.uses_render_area = true;
|
render_area.uses_render_area = true;
|
||||||
|
@ -481,12 +481,13 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
|
||||||
if constexpr (Spec::enabled_stages[4]) {
|
if constexpr (Spec::enabled_stages[4]) {
|
||||||
prepare_stage(4);
|
prepare_stage(4);
|
||||||
}
|
}
|
||||||
|
texture_cache.UpdateRenderTargets(false);
|
||||||
|
texture_cache.CheckFeedbackLoop(views);
|
||||||
ConfigureDraw(rescaling, render_area);
|
ConfigureDraw(rescaling, render_area);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphicsPipeline::ConfigureDraw(const RescalingPushConstant& rescaling,
|
void GraphicsPipeline::ConfigureDraw(const RescalingPushConstant& rescaling,
|
||||||
const RenderAreaPushConstant& render_area) {
|
const RenderAreaPushConstant& render_area) {
|
||||||
texture_cache.UpdateRenderTargets(false);
|
|
||||||
scheduler.RequestRenderpass(texture_cache.GetFramebuffer());
|
scheduler.RequestRenderpass(texture_cache.GetFramebuffer());
|
||||||
|
|
||||||
if (!is_built.load(std::memory_order::relaxed)) {
|
if (!is_built.load(std::memory_order::relaxed)) {
|
||||||
|
|
|
@ -106,15 +106,6 @@ public:
|
||||||
return *master_semaphore;
|
return *master_semaphore;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] bool IsRenderpassImage(VkImage image) const noexcept {
|
|
||||||
for (u32 i = 0; i < num_renderpass_images; i++) {
|
|
||||||
if (image == renderpass_images[i]) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::mutex submit_mutex;
|
std::mutex submit_mutex;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -861,10 +861,8 @@ VkBuffer TextureCacheRuntime::GetTemporaryBuffer(size_t needed_size) {
|
||||||
return *buffers[level];
|
return *buffers[level];
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCacheRuntime::CheckFeedbackLoop(ImageView& image_view) {
|
void TextureCacheRuntime::BarrierFeedbackLoop() {
|
||||||
if (scheduler.IsRenderpassImage(image_view.ImageHandle())) {
|
scheduler.RequestOutsideRenderPassOperationContext();
|
||||||
scheduler.RequestOutsideRenderPassOperationContext();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCacheRuntime::ReinterpretImage(Image& dst, Image& src,
|
void TextureCacheRuntime::ReinterpretImage(Image& dst, Image& src,
|
||||||
|
|
|
@ -103,7 +103,7 @@ public:
|
||||||
|
|
||||||
[[nodiscard]] VkBuffer GetTemporaryBuffer(size_t needed_size);
|
[[nodiscard]] VkBuffer GetTemporaryBuffer(size_t needed_size);
|
||||||
|
|
||||||
void CheckFeedbackLoop(ImageView& image_view);
|
void BarrierFeedbackLoop();
|
||||||
|
|
||||||
const Device& device;
|
const Device& device;
|
||||||
Scheduler& scheduler;
|
Scheduler& scheduler;
|
||||||
|
|
|
@ -182,6 +182,42 @@ void TextureCache<P>::FillComputeImageViews(std::span<ImageViewInOut> views) {
|
||||||
views);
|
views);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class P>
|
||||||
|
void TextureCache<P>::CheckFeedbackLoop(std::span<const ImageViewInOut> views) {
|
||||||
|
const bool requires_barrier = [&] {
|
||||||
|
for (const auto& view : views) {
|
||||||
|
if (!view.id) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto& image_view = slot_image_views[view.id];
|
||||||
|
|
||||||
|
// Check color targets
|
||||||
|
for (const auto& ct_view_id : render_targets.color_buffer_ids) {
|
||||||
|
if (ct_view_id) {
|
||||||
|
auto& ct_view = slot_image_views[ct_view_id];
|
||||||
|
if (image_view.image_id == ct_view.image_id) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check zeta target
|
||||||
|
if (render_targets.depth_buffer_id) {
|
||||||
|
auto& zt_view = slot_image_views[render_targets.depth_buffer_id];
|
||||||
|
if (image_view.image_id == zt_view.image_id) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}();
|
||||||
|
|
||||||
|
if (requires_barrier) {
|
||||||
|
runtime.BarrierFeedbackLoop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <class P>
|
template <class P>
|
||||||
typename P::Sampler* TextureCache<P>::GetGraphicsSampler(u32 index) {
|
typename P::Sampler* TextureCache<P>::GetGraphicsSampler(u32 index) {
|
||||||
if (index > channel_state->graphics_sampler_table.Limit()) {
|
if (index > channel_state->graphics_sampler_table.Limit()) {
|
||||||
|
@ -2374,11 +2410,6 @@ bool TextureCache<P>::IsFullClear(ImageViewId id) {
|
||||||
scissor.max_y >= size.height;
|
scissor.max_y >= size.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class P>
|
|
||||||
void TextureCache<P>::CheckFeedbackLoop(ImageView& image_view) {
|
|
||||||
runtime.CheckFeedbackLoop(image_view);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class P>
|
template <class P>
|
||||||
void TextureCache<P>::CreateChannel(struct Tegra::Control::ChannelState& channel) {
|
void TextureCache<P>::CreateChannel(struct Tegra::Control::ChannelState& channel) {
|
||||||
VideoCommon::ChannelSetupCaches<TextureCacheChannelInfo>::CreateChannel(channel);
|
VideoCommon::ChannelSetupCaches<TextureCacheChannelInfo>::CreateChannel(channel);
|
||||||
|
|
|
@ -148,6 +148,9 @@ public:
|
||||||
/// Fill image_view_ids with the compute images in indices
|
/// Fill image_view_ids with the compute images in indices
|
||||||
void FillComputeImageViews(std::span<ImageViewInOut> views);
|
void FillComputeImageViews(std::span<ImageViewInOut> views);
|
||||||
|
|
||||||
|
/// Handle feedback loops during draws.
|
||||||
|
void CheckFeedbackLoop(std::span<const ImageViewInOut> views);
|
||||||
|
|
||||||
/// Get the sampler from the graphics descriptor table in the specified index
|
/// Get the sampler from the graphics descriptor table in the specified index
|
||||||
Sampler* GetGraphicsSampler(u32 index);
|
Sampler* GetGraphicsSampler(u32 index);
|
||||||
|
|
||||||
|
@ -224,9 +227,6 @@ public:
|
||||||
|
|
||||||
[[nodiscard]] bool IsRescaling(const ImageViewBase& image_view) const noexcept;
|
[[nodiscard]] bool IsRescaling(const ImageViewBase& image_view) const noexcept;
|
||||||
|
|
||||||
/// Handle feedback loops during draws.
|
|
||||||
void CheckFeedbackLoop(ImageView& image_view);
|
|
||||||
|
|
||||||
/// Create channel state.
|
/// Create channel state.
|
||||||
void CreateChannel(Tegra::Control::ChannelState& channel) final override;
|
void CreateChannel(Tegra::Control::ChannelState& channel) final override;
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <stb_dxt.h>
|
#include <stb_dxt.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "common/alignment.h"
|
#include "common/alignment.h"
|
||||||
#include "video_core/textures/bcn.h"
|
#include "video_core/textures/bcn.h"
|
||||||
|
|
Loading…
Reference in a new issue