summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/audio_core/in/audio_in_system.cpp2
-rw-r--r--src/audio_core/in/audio_in_system.h2
-rw-r--r--src/audio_core/out/audio_out_system.cpp4
-rw-r--r--src/audio_core/out/audio_out_system.h4
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_32.cpp2
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.cpp2
-rw-r--r--src/core/file_sys/control_metadata.cpp43
-rw-r--r--src/core/file_sys/control_metadata.h6
-rw-r--r--src/core/hle/service/audio/audin_u.cpp2
-rw-r--r--src/core/hle/service/audio/audout_u.cpp2
-rw-r--r--src/shader_recompiler/frontend/ir/microinstruction.cpp5
-rw-r--r--src/shader_recompiler/frontend/ir/value.h4
-rw-r--r--src/shader_recompiler/ir_opt/dead_code_elimination_pass.cpp98
-rw-r--r--src/video_core/engines/maxwell_3d.cpp129
-rw-r--r--src/video_core/engines/maxwell_3d.h2
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp21
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) {