diff options
-rw-r--r-- | src/audio_core/in/audio_in_system.cpp | 2 | ||||
-rw-r--r-- | src/audio_core/in/audio_in_system.h | 2 | ||||
-rw-r--r-- | src/audio_core/out/audio_out_system.cpp | 4 | ||||
-rw-r--r-- | src/audio_core/out/audio_out_system.h | 4 | ||||
-rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_32.cpp | 2 | ||||
-rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_64.cpp | 2 | ||||
-rw-r--r-- | src/core/file_sys/control_metadata.cpp | 43 | ||||
-rw-r--r-- | src/core/file_sys/control_metadata.h | 6 | ||||
-rw-r--r-- | src/core/hle/service/audio/audin_u.cpp | 2 | ||||
-rw-r--r-- | src/core/hle/service/audio/audout_u.cpp | 2 | ||||
-rw-r--r-- | src/shader_recompiler/frontend/ir/microinstruction.cpp | 5 | ||||
-rw-r--r-- | src/shader_recompiler/frontend/ir/value.h | 4 | ||||
-rw-r--r-- | src/shader_recompiler/ir_opt/dead_code_elimination_pass.cpp | 98 | ||||
-rw-r--r-- | src/video_core/engines/maxwell_3d.cpp | 129 | ||||
-rw-r--r-- | src/video_core/engines/maxwell_3d.h | 2 | ||||
-rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.cpp | 21 |
16 files changed, 139 insertions, 189 deletions
diff --git a/src/audio_core/in/audio_in_system.cpp b/src/audio_core/in/audio_in_system.cpp index 6b7e6715c..4324cafd8 100644 --- a/src/audio_core/in/audio_in_system.cpp +++ b/src/audio_core/in/audio_in_system.cpp @@ -56,7 +56,7 @@ Result System::IsConfigValid(const std::string_view device_name, return ResultSuccess; } -Result System::Initialize(std::string& device_name, const AudioInParameter& in_params, +Result System::Initialize(std::string device_name, const AudioInParameter& in_params, const u32 handle_, const u64 applet_resource_user_id_) { auto result{IsConfigValid(device_name, in_params)}; if (result.IsError()) { diff --git a/src/audio_core/in/audio_in_system.h b/src/audio_core/in/audio_in_system.h index b9dc0e60f..1c5154638 100644 --- a/src/audio_core/in/audio_in_system.h +++ b/src/audio_core/in/audio_in_system.h @@ -97,7 +97,7 @@ public: * @param applet_resource_user_id - Unused. * @return Result code. */ - Result Initialize(std::string& device_name, const AudioInParameter& in_params, u32 handle, + Result Initialize(std::string device_name, const AudioInParameter& in_params, u32 handle, u64 applet_resource_user_id); /** diff --git a/src/audio_core/out/audio_out_system.cpp b/src/audio_core/out/audio_out_system.cpp index 48a801923..a66208ed9 100644 --- a/src/audio_core/out/audio_out_system.cpp +++ b/src/audio_core/out/audio_out_system.cpp @@ -49,8 +49,8 @@ Result System::IsConfigValid(std::string_view device_name, return Service::Audio::ERR_INVALID_CHANNEL_COUNT; } -Result System::Initialize(std::string& device_name, const AudioOutParameter& in_params, u32 handle_, - u64& applet_resource_user_id_) { +Result System::Initialize(std::string device_name, const AudioOutParameter& in_params, u32 handle_, + u64 applet_resource_user_id_) { auto result = IsConfigValid(device_name, in_params); if (result.IsError()) { return result; diff --git a/src/audio_core/out/audio_out_system.h b/src/audio_core/out/audio_out_system.h index 0817b2f37..b95cb91be 100644 --- a/src/audio_core/out/audio_out_system.h +++ b/src/audio_core/out/audio_out_system.h @@ -88,8 +88,8 @@ public: * @param applet_resource_user_id - Unused. * @return Result code. */ - Result Initialize(std::string& device_name, const AudioOutParameter& in_params, u32 handle, - u64& applet_resource_user_id); + Result Initialize(std::string device_name, const AudioOutParameter& in_params, u32 handle, + u64 applet_resource_user_id); /** * Start this system. diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index d1e70f19d..287ba102e 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp @@ -450,7 +450,7 @@ std::vector<ARM_Interface::BacktraceEntry> ARM_Dynarmic_32::GetBacktrace(Core::S // Frame records are two words long: // fp+0 : pointer to previous frame record // fp+4 : value of lr for frame - while (true) { + for (size_t i = 0; i < 256; i++) { out.push_back({"", 0, lr, 0, ""}); if (!fp || (fp % 4 != 0) || !memory.IsValidVirtualAddressRange(fp, 8)) { break; diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index 22b5d5656..afb7fb3a0 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp @@ -517,7 +517,7 @@ std::vector<ARM_Interface::BacktraceEntry> ARM_Dynarmic_64::GetBacktrace(Core::S // Frame records are two words long: // fp+0 : pointer to previous frame record // fp+8 : value of lr for frame - while (true) { + for (size_t i = 0; i < 256; i++) { out.push_back({"", 0, lr, 0, ""}); if (!fp || (fp % 4 != 0) || !memory.IsValidVirtualAddressRange(fp, 16)) { break; diff --git a/src/core/file_sys/control_metadata.cpp b/src/core/file_sys/control_metadata.cpp index be25da2f6..50f44f598 100644 --- a/src/core/file_sys/control_metadata.cpp +++ b/src/core/file_sys/control_metadata.cpp @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include "common/settings.h" #include "common/string_util.h" #include "common/swap.h" #include "core/file_sys/control_metadata.h" @@ -37,6 +38,27 @@ std::string LanguageEntry::GetDeveloperName() const { developer_name.size()); } +constexpr std::array<Language, 18> language_to_codes = {{ + Language::Japanese, + Language::AmericanEnglish, + Language::French, + Language::German, + Language::Italian, + Language::Spanish, + Language::Chinese, + Language::Korean, + Language::Dutch, + Language::Portuguese, + Language::Russian, + Language::Taiwanese, + Language::BritishEnglish, + Language::CanadianFrench, + Language::LatinAmericanSpanish, + Language::Chinese, + Language::Taiwanese, + Language::BrazilianPortuguese, +}}; + NACP::NACP() = default; NACP::NACP(VirtualFile file) { @@ -45,9 +67,13 @@ NACP::NACP(VirtualFile file) { NACP::~NACP() = default; -const LanguageEntry& NACP::GetLanguageEntry(Language language) const { - if (language != Language::Default) { - return raw.language_entries.at(static_cast<u8>(language)); +const LanguageEntry& NACP::GetLanguageEntry() const { + Language language = language_to_codes[Settings::values.language_index.GetValue()]; + + { + const auto& language_entry = raw.language_entries.at(static_cast<u8>(language)); + if (!language_entry.GetApplicationName().empty()) + return language_entry; } for (const auto& language_entry : raw.language_entries) { @@ -55,16 +81,15 @@ const LanguageEntry& NACP::GetLanguageEntry(Language language) const { return language_entry; } - // Fallback to English - return GetLanguageEntry(Language::AmericanEnglish); + return raw.language_entries.at(static_cast<u8>(Language::AmericanEnglish)); } -std::string NACP::GetApplicationName(Language language) const { - return GetLanguageEntry(language).GetApplicationName(); +std::string NACP::GetApplicationName() const { + return GetLanguageEntry().GetApplicationName(); } -std::string NACP::GetDeveloperName(Language language) const { - return GetLanguageEntry(language).GetDeveloperName(); +std::string NACP::GetDeveloperName() const { + return GetLanguageEntry().GetDeveloperName(); } u64 NACP::GetTitleId() const { diff --git a/src/core/file_sys/control_metadata.h b/src/core/file_sys/control_metadata.h index 75295519c..6a81873b1 100644 --- a/src/core/file_sys/control_metadata.h +++ b/src/core/file_sys/control_metadata.h @@ -101,9 +101,9 @@ public: explicit NACP(VirtualFile file); ~NACP(); - const LanguageEntry& GetLanguageEntry(Language language = Language::Default) const; - std::string GetApplicationName(Language language = Language::Default) const; - std::string GetDeveloperName(Language language = Language::Default) const; + const LanguageEntry& GetLanguageEntry() const; + std::string GetApplicationName() const; + std::string GetDeveloperName() const; u64 GetTitleId() const; u64 GetDLCBaseTitleId() const; std::string GetVersionString() const; diff --git a/src/core/hle/service/audio/audin_u.cpp b/src/core/hle/service/audio/audin_u.cpp index 48a9a73a0..608925dfc 100644 --- a/src/core/hle/service/audio/audin_u.cpp +++ b/src/core/hle/service/audio/audin_u.cpp @@ -17,7 +17,7 @@ using namespace AudioCore::AudioIn; class IAudioIn final : public ServiceFramework<IAudioIn> { public: explicit IAudioIn(Core::System& system_, Manager& manager, size_t session_id, - std::string& device_name, const AudioInParameter& in_params, u32 handle, + const std::string& device_name, const AudioInParameter& in_params, u32 handle, u64 applet_resource_user_id) : ServiceFramework{system_, "IAudioIn"}, service_context{system_, "IAudioIn"}, event{service_context.CreateEvent("AudioInEvent")}, diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp index 49c092301..122290c6a 100644 --- a/src/core/hle/service/audio/audout_u.cpp +++ b/src/core/hle/service/audio/audout_u.cpp @@ -24,7 +24,7 @@ using namespace AudioCore::AudioOut; class IAudioOut final : public ServiceFramework<IAudioOut> { public: explicit IAudioOut(Core::System& system_, AudioCore::AudioOut::Manager& manager, - size_t session_id, std::string& device_name, + size_t session_id, const std::string& device_name, const AudioOutParameter& in_params, u32 handle, u64 applet_resource_user_id) : ServiceFramework{system_, "IAudioOut", ServiceThreadType::CreateNew}, service_context{system_, "IAudioOut"}, event{service_context.CreateEvent( diff --git a/src/shader_recompiler/frontend/ir/microinstruction.cpp b/src/shader_recompiler/frontend/ir/microinstruction.cpp index 468782eb1..84417980b 100644 --- a/src/shader_recompiler/frontend/ir/microinstruction.cpp +++ b/src/shader_recompiler/frontend/ir/microinstruction.cpp @@ -325,11 +325,6 @@ void Inst::AddPhiOperand(Block* predecessor, const Value& value) { phi_args.emplace_back(predecessor, value); } -void Inst::ErasePhiOperand(size_t index) { - const auto operand_it{phi_args.begin() + static_cast<ptrdiff_t>(index)}; - phi_args.erase(operand_it); -} - void Inst::OrderPhiArgs() { if (op != Opcode::Phi) { throw LogicError("{} is not a Phi instruction", op); diff --git a/src/shader_recompiler/frontend/ir/value.h b/src/shader_recompiler/frontend/ir/value.h index 1a2e4ccb6..6a673ca05 100644 --- a/src/shader_recompiler/frontend/ir/value.h +++ b/src/shader_recompiler/frontend/ir/value.h @@ -178,13 +178,9 @@ public: /// Get a pointer to the block of a phi argument. [[nodiscard]] Block* PhiBlock(size_t index) const; - /// Add phi operand to a phi instruction. void AddPhiOperand(Block* predecessor, const Value& value); - // Erase the phi operand at the given index. - void ErasePhiOperand(size_t index); - /// Orders the Phi arguments from farthest away to nearest. void OrderPhiArgs(); diff --git a/src/shader_recompiler/ir_opt/dead_code_elimination_pass.cpp b/src/shader_recompiler/ir_opt/dead_code_elimination_pass.cpp index 9a7d47344..1bd8afd6f 100644 --- a/src/shader_recompiler/ir_opt/dead_code_elimination_pass.cpp +++ b/src/shader_recompiler/ir_opt/dead_code_elimination_pass.cpp @@ -1,104 +1,24 @@ // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include <algorithm> - -#include <boost/container/small_vector.hpp> - #include "shader_recompiler/frontend/ir/basic_block.h" #include "shader_recompiler/frontend/ir/value.h" #include "shader_recompiler/ir_opt/passes.h" namespace Shader::Optimization { -namespace { -template <bool TEST_USES> -void DeadInstElimination(IR::Block* const block) { + +void DeadCodeEliminationPass(IR::Program& program) { // We iterate over the instructions in reverse order. // This is because removing an instruction reduces the number of uses for earlier instructions. - auto it{block->end()}; - while (it != block->begin()) { - --it; - if constexpr (TEST_USES) { - if (it->HasUses() || it->MayHaveSideEffects()) { - continue; - } - } - it->Invalidate(); - it = block->Instructions().erase(it); - } -} - -void DeletedPhiArgElimination(IR::Program& program, std::span<const IR::Block*> dead_blocks) { - for (IR::Block* const block : program.blocks) { - for (IR::Inst& phi : *block) { - if (!IR::IsPhi(phi)) { - continue; - } - for (size_t i = 0; i < phi.NumArgs(); ++i) { - if (std::ranges::find(dead_blocks, phi.PhiBlock(i)) == dead_blocks.end()) { - continue; - } - // Phi operand at this index is an unreachable block - phi.ErasePhiOperand(i); - --i; - } - } - } -} - -void DeadBranchElimination(IR::Program& program) { - boost::container::small_vector<const IR::Block*, 3> dead_blocks; - const auto begin_it{program.syntax_list.begin()}; - for (auto node_it = begin_it; node_it != program.syntax_list.end(); ++node_it) { - if (node_it->type != IR::AbstractSyntaxNode::Type::If) { - continue; - } - IR::Inst* const cond_ref{node_it->data.if_node.cond.Inst()}; - const IR::U1 cond{cond_ref->Arg(0)}; - if (!cond.IsImmediate()) { - continue; - } - if (cond.U1()) { - continue; - } - // False immediate condition. Remove condition ref, erase the entire branch. - cond_ref->Invalidate(); - // Account for nested if-statements within the if(false) branch - u32 nested_ifs{1u}; - while (node_it->type != IR::AbstractSyntaxNode::Type::EndIf || nested_ifs > 0) { - node_it = program.syntax_list.erase(node_it); - switch (node_it->type) { - case IR::AbstractSyntaxNode::Type::If: - ++nested_ifs; - break; - case IR::AbstractSyntaxNode::Type::EndIf: - --nested_ifs; - break; - case IR::AbstractSyntaxNode::Type::Block: { - IR::Block* const block{node_it->data.block}; - DeadInstElimination<false>(block); - dead_blocks.push_back(block); - break; - } - default: - break; + for (IR::Block* const block : program.post_order_blocks) { + auto it{block->end()}; + while (it != block->begin()) { + --it; + if (!it->HasUses() && !it->MayHaveSideEffects()) { + it->Invalidate(); + it = block->Instructions().erase(it); } } - // Erase EndIf node of the if(false) branch - node_it = program.syntax_list.erase(node_it); - // Account for loop increment - --node_it; - } - if (!dead_blocks.empty()) { - DeletedPhiArgElimination(program, std::span(dead_blocks.data(), dead_blocks.size())); - } -} -} // namespace - -void DeadCodeEliminationPass(IR::Program& program) { - DeadBranchElimination(program); - for (IR::Block* const block : program.post_order_blocks) { - DeadInstElimination<true>(block); } } diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 5208bea75..f9794dfe4 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -123,9 +123,6 @@ void Maxwell3D::InitializeRegisterDefaults() { draw_command[MAXWELL3D_REG_INDEX(vertex_buffer.count)] = true; draw_command[MAXWELL3D_REG_INDEX(index_buffer.first)] = true; draw_command[MAXWELL3D_REG_INDEX(index_buffer.count)] = true; - draw_command[MAXWELL3D_REG_INDEX(index_buffer32_first)] = true; - draw_command[MAXWELL3D_REG_INDEX(index_buffer16_first)] = true; - draw_command[MAXWELL3D_REG_INDEX(index_buffer8_first)] = true; draw_command[MAXWELL3D_REG_INDEX(draw_inline_index)] = true; draw_command[MAXWELL3D_REG_INDEX(inline_index_2x16.even)] = true; draw_command[MAXWELL3D_REG_INDEX(inline_index_4x8.index0)] = true; @@ -216,6 +213,21 @@ void Maxwell3D::ProcessMethodCall(u32 method, u32 argument, u32 nonshadow_argume return ProcessCBBind(3); case MAXWELL3D_REG_INDEX(bind_groups[4].raw_config): return ProcessCBBind(4); + case MAXWELL3D_REG_INDEX(index_buffer32_first): + regs.index_buffer.count = regs.index_buffer32_first.count; + regs.index_buffer.first = regs.index_buffer32_first.first; + dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; + return ProcessDraw(); + case MAXWELL3D_REG_INDEX(index_buffer16_first): + regs.index_buffer.count = regs.index_buffer16_first.count; + regs.index_buffer.first = regs.index_buffer16_first.first; + dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; + return ProcessDraw(); + case MAXWELL3D_REG_INDEX(index_buffer8_first): + regs.index_buffer.count = regs.index_buffer8_first.count; + regs.index_buffer.first = regs.index_buffer8_first.first; + dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; + return ProcessDraw(); case MAXWELL3D_REG_INDEX(topology_override): use_topology_override = true; return; @@ -583,6 +595,31 @@ void Maxwell3D::ProcessClearBuffers() { rasterizer->Clear(); } +void Maxwell3D::ProcessDraw(u32 instance_count) { + LOG_TRACE(HW_GPU, "called, topology={}, count={}", regs.draw.topology.Value(), + regs.vertex_buffer.count); + + ASSERT_MSG(!(regs.index_buffer.count && regs.vertex_buffer.count), "Both indexed and direct?"); + + // Both instance configuration registers can not be set at the same time. + ASSERT_MSG(regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::First || + regs.draw.instance_id != Maxwell3D::Regs::Draw::InstanceId::Unchanged, + "Illegal combination of instancing parameters"); + + ProcessTopologyOverride(); + + const bool is_indexed = regs.index_buffer.count && !regs.vertex_buffer.count; + if (ShouldExecute()) { + rasterizer->Draw(is_indexed, instance_count); + } + + if (is_indexed) { + regs.index_buffer.count = 0; + } else { + regs.vertex_buffer.count = 0; + } +} + void Maxwell3D::ProcessDeferredDraw() { if (deferred_draw_method.empty()) { return; @@ -596,23 +633,28 @@ void Maxwell3D::ProcessDeferredDraw() { DrawMode draw_mode{DrawMode::Undefined}; u32 instance_count = 1; - auto first_method = deferred_draw_method[0]; - if (MAXWELL3D_REG_INDEX(draw.begin) == first_method) { - // The minimum number of methods for drawing must be greater than or equal to - // 3[draw.begin->vertex(index)count->draw.end] to avoid errors in index mode drawing - if (deferred_draw_method.size() < 3) { - return; - } - draw_mode = (regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::Subsequent) || - (regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::Unchanged) - ? DrawMode::Instance - : DrawMode::General; - } else if (MAXWELL3D_REG_INDEX(index_buffer32_first) == first_method || - MAXWELL3D_REG_INDEX(index_buffer16_first) == first_method || - MAXWELL3D_REG_INDEX(index_buffer8_first) == first_method) { - draw_mode = DrawMode::General; + u32 index = 0; + u32 method = 0; + u32 method_count = static_cast<u32>(deferred_draw_method.size()); + for (; index < method_count && + (method = deferred_draw_method[index]) != MAXWELL3D_REG_INDEX(draw.begin); + ++index) + ; + + if (MAXWELL3D_REG_INDEX(draw.begin) != method) { + return; } + // The minimum number of methods for drawing must be greater than or equal to + // 3[draw.begin->vertex(index)count(first)->draw.end] to avoid errors in index mode drawing + if ((method_count - index) < 3) { + return; + } + draw_mode = (regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::Subsequent) || + (regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::Unchanged) + ? DrawMode::Instance + : DrawMode::General; + // Drawing will only begin with draw.begin or index_buffer method, other methods directly // clear if (draw_mode == DrawMode::Undefined) { @@ -622,53 +664,18 @@ void Maxwell3D::ProcessDeferredDraw() { if (draw_mode == DrawMode::Instance) { ASSERT_MSG(deferred_draw_method.size() % 4 == 0, "Instance mode method size error"); - instance_count = static_cast<u32>(deferred_draw_method.size()) / 4; + instance_count = static_cast<u32>(method_count - index) / 4; } else { - if (MAXWELL3D_REG_INDEX(index_buffer32_first) == first_method) { - regs.index_buffer.count = regs.index_buffer32_first.count; - regs.index_buffer.first = regs.index_buffer32_first.first; - dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; - } else if (MAXWELL3D_REG_INDEX(index_buffer32_first) == first_method) { - regs.index_buffer.count = regs.index_buffer16_first.count; - regs.index_buffer.first = regs.index_buffer16_first.first; - dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; - } else if (MAXWELL3D_REG_INDEX(index_buffer32_first) == first_method) { - regs.index_buffer.count = regs.index_buffer8_first.count; - regs.index_buffer.first = regs.index_buffer8_first.first; - dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; - } else { - auto second_method = deferred_draw_method[1]; - if (MAXWELL3D_REG_INDEX(draw_inline_index) == second_method || - MAXWELL3D_REG_INDEX(inline_index_2x16.even) == second_method || - MAXWELL3D_REG_INDEX(inline_index_4x8.index0) == second_method) { - regs.index_buffer.count = static_cast<u32>(inline_index_draw_indexes.size() / 4); - regs.index_buffer.format = Regs::IndexFormat::UnsignedInt; - } + method = deferred_draw_method[index + 1]; + if (MAXWELL3D_REG_INDEX(draw_inline_index) == method || + MAXWELL3D_REG_INDEX(inline_index_2x16.even) == method || + MAXWELL3D_REG_INDEX(inline_index_4x8.index0) == method) { + regs.index_buffer.count = static_cast<u32>(inline_index_draw_indexes.size() / 4); + regs.index_buffer.format = Regs::IndexFormat::UnsignedInt; } } - LOG_TRACE(HW_GPU, "called, topology={}, count={}", regs.draw.topology.Value(), - regs.vertex_buffer.count); - - ASSERT_MSG(!(regs.index_buffer.count && regs.vertex_buffer.count), "Both indexed and direct?"); - - // Both instance configuration registers can not be set at the same time. - ASSERT_MSG(regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::First || - regs.draw.instance_id != Maxwell3D::Regs::Draw::InstanceId::Unchanged, - "Illegal combination of instancing parameters"); - - ProcessTopologyOverride(); - - const bool is_indexed = regs.index_buffer.count && !regs.vertex_buffer.count; - if (ShouldExecute()) { - rasterizer->Draw(is_indexed, instance_count); - } - - if (is_indexed) { - regs.index_buffer.count = 0; - } else { - regs.vertex_buffer.count = 0; - } + ProcessDraw(instance_count); deferred_draw_method.clear(); inline_index_draw_indexes.clear(); diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index bd23ebc12..a948fcb14 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -3143,6 +3143,8 @@ private: /// Handles use of topology overrides (e.g., to avoid using a topology assigned from a macro) void ProcessTopologyOverride(); + void ProcessDraw(u32 instance_count = 1); + void ProcessDeferredDraw(); /// Returns a query's value or an empty object if the value will be deferred through a cache. diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 9f05a7a18..6ab68892c 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -305,14 +305,19 @@ void RasterizerVulkan::Clear() { } } - scheduler.Record([color_attachment, clear_value, clear_rect](vk::CommandBuffer cmdbuf) { - const VkClearAttachment attachment{ - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - .colorAttachment = color_attachment, - .clearValue = clear_value, - }; - cmdbuf.ClearAttachments(attachment, clear_rect); - }); + 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, + .colorAttachment = color_attachment, + .clearValue = clear_value, + }; + cmdbuf.ClearAttachments(attachment, clear_rect); + }); + } else { + UNIMPLEMENTED_MSG("Unimplemented Clear only the specified channel"); + } } if (!use_depth && !use_stencil) { |