diff options
| -rw-r--r-- | src/audio_core/audio_renderer.cpp | 19 | ||||
| -rw-r--r-- | src/audio_core/audio_renderer.h | 13 | ||||
| -rw-r--r-- | src/core/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_32.cpp | 2 | ||||
| -rw-r--r-- | src/core/file_sys/system_archive/mii_model.cpp | 2 | ||||
| -rw-r--r-- | src/input_common/keyboard.cpp | 2 | ||||
| -rw-r--r-- | src/input_common/motion_emu.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/macro/macro_jit_x64.cpp | 42 | ||||
| -rw-r--r-- | src/video_core/macro/macro_jit_x64.h | 1 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/maxwell_to_gl.h | 82 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/maxwell_to_vk.cpp | 32 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_sampler_cache.cpp | 6 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_service.cpp | 6 |
13 files changed, 117 insertions, 96 deletions
diff --git a/src/audio_core/audio_renderer.cpp b/src/audio_core/audio_renderer.cpp index 50846a854..d64452617 100644 --- a/src/audio_core/audio_renderer.cpp +++ b/src/audio_core/audio_renderer.cpp | |||
| @@ -180,11 +180,12 @@ ResultVal<std::vector<u8>> AudioRenderer::UpdateAudioRenderer(const std::vector< | |||
| 180 | 180 | ||
| 181 | // Copy output header | 181 | // Copy output header |
| 182 | UpdateDataHeader response_data{worker_params}; | 182 | UpdateDataHeader response_data{worker_params}; |
| 183 | std::vector<u8> output_params(response_data.total_size); | ||
| 184 | if (behavior_info.IsElapsedFrameCountSupported()) { | 183 | if (behavior_info.IsElapsedFrameCountSupported()) { |
| 185 | response_data.frame_count = 0x10; | 184 | response_data.render_info = sizeof(RendererInfo); |
| 186 | response_data.total_size += 0x10; | 185 | response_data.total_size += sizeof(RendererInfo); |
| 187 | } | 186 | } |
| 187 | |||
| 188 | std::vector<u8> output_params(response_data.total_size); | ||
| 188 | std::memcpy(output_params.data(), &response_data, sizeof(UpdateDataHeader)); | 189 | std::memcpy(output_params.data(), &response_data, sizeof(UpdateDataHeader)); |
| 189 | 190 | ||
| 190 | // Copy output memory pool entries | 191 | // Copy output memory pool entries |
| @@ -219,6 +220,17 @@ ResultVal<std::vector<u8>> AudioRenderer::UpdateAudioRenderer(const std::vector< | |||
| 219 | return Audren::ERR_INVALID_PARAMETERS; | 220 | return Audren::ERR_INVALID_PARAMETERS; |
| 220 | } | 221 | } |
| 221 | 222 | ||
| 223 | if (behavior_info.IsElapsedFrameCountSupported()) { | ||
| 224 | const std::size_t renderer_info_offset{ | ||
| 225 | sizeof(UpdateDataHeader) + response_data.memory_pools_size + response_data.voices_size + | ||
| 226 | response_data.effects_size + response_data.sinks_size + | ||
| 227 | response_data.performance_manager_size + response_data.behavior_size}; | ||
| 228 | RendererInfo renderer_info{}; | ||
| 229 | renderer_info.elasped_frame_count = elapsed_frame_count; | ||
| 230 | std::memcpy(output_params.data() + renderer_info_offset, &renderer_info, | ||
| 231 | sizeof(RendererInfo)); | ||
| 232 | } | ||
| 233 | |||
| 222 | return MakeResult(output_params); | 234 | return MakeResult(output_params); |
| 223 | } | 235 | } |
| 224 | 236 | ||
| @@ -447,6 +459,7 @@ void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) { | |||
| 447 | } | 459 | } |
| 448 | } | 460 | } |
| 449 | audio_out->QueueBuffer(stream, tag, std::move(buffer)); | 461 | audio_out->QueueBuffer(stream, tag, std::move(buffer)); |
| 462 | elapsed_frame_count++; | ||
| 450 | } | 463 | } |
| 451 | 464 | ||
| 452 | void AudioRenderer::ReleaseAndQueueBuffers() { | 465 | void AudioRenderer::ReleaseAndQueueBuffers() { |
diff --git a/src/audio_core/audio_renderer.h b/src/audio_core/audio_renderer.h index 1f9114c07..f0b691a86 100644 --- a/src/audio_core/audio_renderer.h +++ b/src/audio_core/audio_renderer.h | |||
| @@ -196,6 +196,12 @@ struct EffectOutStatus { | |||
| 196 | }; | 196 | }; |
| 197 | static_assert(sizeof(EffectOutStatus) == 0x10, "EffectOutStatus is an invalid size"); | 197 | static_assert(sizeof(EffectOutStatus) == 0x10, "EffectOutStatus is an invalid size"); |
| 198 | 198 | ||
| 199 | struct RendererInfo { | ||
| 200 | u64_le elasped_frame_count{}; | ||
| 201 | INSERT_PADDING_WORDS(2); | ||
| 202 | }; | ||
| 203 | static_assert(sizeof(RendererInfo) == 0x10, "RendererInfo is an invalid size"); | ||
| 204 | |||
| 199 | struct UpdateDataHeader { | 205 | struct UpdateDataHeader { |
| 200 | UpdateDataHeader() {} | 206 | UpdateDataHeader() {} |
| 201 | 207 | ||
| @@ -209,7 +215,7 @@ struct UpdateDataHeader { | |||
| 209 | mixes_size = 0x0; | 215 | mixes_size = 0x0; |
| 210 | sinks_size = config.sink_count * 0x20; | 216 | sinks_size = config.sink_count * 0x20; |
| 211 | performance_manager_size = 0x10; | 217 | performance_manager_size = 0x10; |
| 212 | frame_count = 0; | 218 | render_info = 0; |
| 213 | total_size = sizeof(UpdateDataHeader) + behavior_size + memory_pools_size + voices_size + | 219 | total_size = sizeof(UpdateDataHeader) + behavior_size + memory_pools_size + voices_size + |
| 214 | effects_size + sinks_size + performance_manager_size; | 220 | effects_size + sinks_size + performance_manager_size; |
| 215 | } | 221 | } |
| @@ -223,8 +229,8 @@ struct UpdateDataHeader { | |||
| 223 | u32_le mixes_size{}; | 229 | u32_le mixes_size{}; |
| 224 | u32_le sinks_size{}; | 230 | u32_le sinks_size{}; |
| 225 | u32_le performance_manager_size{}; | 231 | u32_le performance_manager_size{}; |
| 226 | INSERT_PADDING_WORDS(1); | 232 | u32_le splitter_size{}; |
| 227 | u32_le frame_count{}; | 233 | u32_le render_info{}; |
| 228 | INSERT_PADDING_WORDS(4); | 234 | INSERT_PADDING_WORDS(4); |
| 229 | u32_le total_size{}; | 235 | u32_le total_size{}; |
| 230 | }; | 236 | }; |
| @@ -258,6 +264,7 @@ private: | |||
| 258 | std::unique_ptr<AudioOut> audio_out; | 264 | std::unique_ptr<AudioOut> audio_out; |
| 259 | StreamPtr stream; | 265 | StreamPtr stream; |
| 260 | Core::Memory::Memory& memory; | 266 | Core::Memory::Memory& memory; |
| 267 | std::size_t elapsed_frame_count{}; | ||
| 261 | }; | 268 | }; |
| 262 | 269 | ||
| 263 | } // namespace AudioCore | 270 | } // namespace AudioCore |
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 47418006b..cb9ced5c9 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -606,11 +606,11 @@ endif() | |||
| 606 | create_target_directory_groups(core) | 606 | create_target_directory_groups(core) |
| 607 | 607 | ||
| 608 | target_link_libraries(core PUBLIC common PRIVATE audio_core video_core) | 608 | target_link_libraries(core PUBLIC common PRIVATE audio_core video_core) |
| 609 | target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt::fmt nlohmann_json::nlohmann_json mbedtls Opus::Opus unicorn) | 609 | target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt::fmt nlohmann_json::nlohmann_json mbedtls Opus::Opus unicorn zip) |
| 610 | 610 | ||
| 611 | if (YUZU_ENABLE_BOXCAT) | 611 | if (YUZU_ENABLE_BOXCAT) |
| 612 | target_compile_definitions(core PRIVATE -DYUZU_ENABLE_BOXCAT) | 612 | target_compile_definitions(core PRIVATE -DYUZU_ENABLE_BOXCAT) |
| 613 | target_link_libraries(core PRIVATE httplib nlohmann_json::nlohmann_json zip) | 613 | target_link_libraries(core PRIVATE httplib nlohmann_json::nlohmann_json) |
| 614 | endif() | 614 | endif() |
| 615 | 615 | ||
| 616 | if (ENABLE_WEB_SERVICE) | 616 | if (ENABLE_WEB_SERVICE) |
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index e7456a8c3..19d798dc7 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp | |||
| @@ -165,7 +165,7 @@ u64 ARM_Dynarmic_32::GetTPIDR_EL0() const { | |||
| 165 | } | 165 | } |
| 166 | 166 | ||
| 167 | void ARM_Dynarmic_32::SetTPIDR_EL0(u64 value) { | 167 | void ARM_Dynarmic_32::SetTPIDR_EL0(u64 value) { |
| 168 | cp15->uprw = value; | 168 | cp15->uprw = static_cast<u32>(value); |
| 169 | } | 169 | } |
| 170 | 170 | ||
| 171 | void ARM_Dynarmic_32::SaveContext(ThreadContext32& ctx) { | 171 | void ARM_Dynarmic_32::SaveContext(ThreadContext32& ctx) { |
diff --git a/src/core/file_sys/system_archive/mii_model.cpp b/src/core/file_sys/system_archive/mii_model.cpp index 6a9add87c..61bb67945 100644 --- a/src/core/file_sys/system_archive/mii_model.cpp +++ b/src/core/file_sys/system_archive/mii_model.cpp | |||
| @@ -40,7 +40,7 @@ VirtualDir MiiModel() { | |||
| 40 | out->AddFile(std::make_shared<ArrayVfsFile<MiiModelData::SHAPE_MID.size()>>( | 40 | out->AddFile(std::make_shared<ArrayVfsFile<MiiModelData::SHAPE_MID.size()>>( |
| 41 | MiiModelData::SHAPE_MID, "ShapeMid.dat")); | 41 | MiiModelData::SHAPE_MID, "ShapeMid.dat")); |
| 42 | 42 | ||
| 43 | return std::move(out); | 43 | return out; |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | } // namespace FileSys::SystemArchive | 46 | } // namespace FileSys::SystemArchive |
diff --git a/src/input_common/keyboard.cpp b/src/input_common/keyboard.cpp index 078374be5..afb8e6612 100644 --- a/src/input_common/keyboard.cpp +++ b/src/input_common/keyboard.cpp | |||
| @@ -76,7 +76,7 @@ std::unique_ptr<Input::ButtonDevice> Keyboard::Create(const Common::ParamPackage | |||
| 76 | int key_code = params.Get("code", 0); | 76 | int key_code = params.Get("code", 0); |
| 77 | std::unique_ptr<KeyButton> button = std::make_unique<KeyButton>(key_button_list); | 77 | std::unique_ptr<KeyButton> button = std::make_unique<KeyButton>(key_button_list); |
| 78 | key_button_list->AddKeyButton(key_code, button.get()); | 78 | key_button_list->AddKeyButton(key_code, button.get()); |
| 79 | return std::move(button); | 79 | return button; |
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | void Keyboard::PressKey(int key_code) { | 82 | void Keyboard::PressKey(int key_code) { |
diff --git a/src/input_common/motion_emu.cpp b/src/input_common/motion_emu.cpp index 868251628..d4cdf76a3 100644 --- a/src/input_common/motion_emu.cpp +++ b/src/input_common/motion_emu.cpp | |||
| @@ -145,7 +145,7 @@ std::unique_ptr<Input::MotionDevice> MotionEmu::Create(const Common::ParamPackag | |||
| 145 | // Previously created device is disconnected here. Having two motion devices for 3DS is not | 145 | // Previously created device is disconnected here. Having two motion devices for 3DS is not |
| 146 | // expected. | 146 | // expected. |
| 147 | current_device = device_wrapper->device; | 147 | current_device = device_wrapper->device; |
| 148 | return std::move(device_wrapper); | 148 | return device_wrapper; |
| 149 | } | 149 | } |
| 150 | 150 | ||
| 151 | void MotionEmu::BeginTilt(int x, int y) { | 151 | void MotionEmu::BeginTilt(int x, int y) { |
diff --git a/src/video_core/macro/macro_jit_x64.cpp b/src/video_core/macro/macro_jit_x64.cpp index d4a97ec7b..79434a63c 100644 --- a/src/video_core/macro/macro_jit_x64.cpp +++ b/src/video_core/macro/macro_jit_x64.cpp | |||
| @@ -56,11 +56,13 @@ void MacroJITx64Impl::Compile_ALU(Macro::Opcode opcode) { | |||
| 56 | const bool valid_operation = !is_a_zero && !is_b_zero; | 56 | const bool valid_operation = !is_a_zero && !is_b_zero; |
| 57 | const bool is_move_operation = !is_a_zero && is_b_zero; | 57 | const bool is_move_operation = !is_a_zero && is_b_zero; |
| 58 | const bool has_zero_register = is_a_zero || is_b_zero; | 58 | const bool has_zero_register = is_a_zero || is_b_zero; |
| 59 | const bool no_zero_reg_skip = opcode.alu_operation == Macro::ALUOperation::AddWithCarry || | ||
| 60 | opcode.alu_operation == Macro::ALUOperation::SubtractWithBorrow; | ||
| 59 | 61 | ||
| 60 | Xbyak::Reg32 src_a; | 62 | Xbyak::Reg32 src_a; |
| 61 | Xbyak::Reg32 src_b; | 63 | Xbyak::Reg32 src_b; |
| 62 | 64 | ||
| 63 | if (!optimizer.zero_reg_skip) { | 65 | if (!optimizer.zero_reg_skip || no_zero_reg_skip) { |
| 64 | src_a = Compile_GetRegister(opcode.src_a, RESULT); | 66 | src_a = Compile_GetRegister(opcode.src_a, RESULT); |
| 65 | src_b = Compile_GetRegister(opcode.src_b, eax); | 67 | src_b = Compile_GetRegister(opcode.src_b, eax); |
| 66 | } else { | 68 | } else { |
| @@ -183,7 +185,8 @@ void MacroJITx64Impl::Compile_AddImmediate(Macro::Opcode opcode) { | |||
| 183 | opcode.result_operation == Macro::ResultOperation::MoveAndSetMethod) { | 185 | opcode.result_operation == Macro::ResultOperation::MoveAndSetMethod) { |
| 184 | if (next_opcode.has_value()) { | 186 | if (next_opcode.has_value()) { |
| 185 | const auto next = *next_opcode; | 187 | const auto next = *next_opcode; |
| 186 | if (next.result_operation == Macro::ResultOperation::MoveAndSetMethod) { | 188 | if (next.result_operation == Macro::ResultOperation::MoveAndSetMethod && |
| 189 | opcode.dst == next.dst) { | ||
| 187 | return; | 190 | return; |
| 188 | } | 191 | } |
| 189 | } | 192 | } |
| @@ -270,14 +273,6 @@ void MacroJITx64Impl::Compile_ExtractShiftLeftRegister(Macro::Opcode opcode) { | |||
| 270 | Compile_ProcessResult(opcode.result_operation, opcode.dst); | 273 | Compile_ProcessResult(opcode.result_operation, opcode.dst); |
| 271 | } | 274 | } |
| 272 | 275 | ||
| 273 | static u32 Read(Engines::Maxwell3D* maxwell3d, u32 method) { | ||
| 274 | return maxwell3d->GetRegisterValue(method); | ||
| 275 | } | ||
| 276 | |||
| 277 | static void Send(Engines::Maxwell3D* maxwell3d, Macro::MethodAddress method_address, u32 value) { | ||
| 278 | maxwell3d->CallMethodFromMME(method_address.address, value); | ||
| 279 | } | ||
| 280 | |||
| 281 | void MacroJITx64Impl::Compile_Read(Macro::Opcode opcode) { | 276 | void MacroJITx64Impl::Compile_Read(Macro::Opcode opcode) { |
| 282 | if (optimizer.zero_reg_skip && opcode.src_a == 0) { | 277 | if (optimizer.zero_reg_skip && opcode.src_a == 0) { |
| 283 | if (opcode.immediate == 0) { | 278 | if (opcode.immediate == 0) { |
| @@ -295,15 +290,27 @@ void MacroJITx64Impl::Compile_Read(Macro::Opcode opcode) { | |||
| 295 | sub(result, opcode.immediate * -1); | 290 | sub(result, opcode.immediate * -1); |
| 296 | } | 291 | } |
| 297 | } | 292 | } |
| 298 | Common::X64::ABI_PushRegistersAndAdjustStack(*this, PersistentCallerSavedRegs(), 0); | 293 | |
| 299 | mov(Common::X64::ABI_PARAM1, qword[STATE]); | 294 | // Equivalent to Engines::Maxwell3D::GetRegisterValue: |
| 300 | mov(Common::X64::ABI_PARAM2, RESULT); | 295 | if (optimizer.enable_asserts) { |
| 301 | Common::X64::CallFarFunction(*this, &Read); | 296 | Xbyak::Label pass_range_check; |
| 302 | Common::X64::ABI_PopRegistersAndAdjustStack(*this, PersistentCallerSavedRegs(), 0); | 297 | cmp(RESULT, static_cast<u32>(Engines::Maxwell3D::Regs::NUM_REGS)); |
| 303 | mov(RESULT, Common::X64::ABI_RETURN.cvt32()); | 298 | jb(pass_range_check); |
| 299 | int3(); | ||
| 300 | L(pass_range_check); | ||
| 301 | } | ||
| 302 | mov(rax, qword[STATE]); | ||
| 303 | mov(RESULT, | ||
| 304 | dword[rax + offsetof(Engines::Maxwell3D, regs) + | ||
| 305 | offsetof(Engines::Maxwell3D::Regs, reg_array) + RESULT.cvt64() * sizeof(u32)]); | ||
| 306 | |||
| 304 | Compile_ProcessResult(opcode.result_operation, opcode.dst); | 307 | Compile_ProcessResult(opcode.result_operation, opcode.dst); |
| 305 | } | 308 | } |
| 306 | 309 | ||
| 310 | static void Send(Engines::Maxwell3D* maxwell3d, Macro::MethodAddress method_address, u32 value) { | ||
| 311 | maxwell3d->CallMethodFromMME(method_address.address, value); | ||
| 312 | } | ||
| 313 | |||
| 307 | void Tegra::MacroJITx64Impl::Compile_Send(Xbyak::Reg32 value) { | 314 | void Tegra::MacroJITx64Impl::Compile_Send(Xbyak::Reg32 value) { |
| 308 | Common::X64::ABI_PushRegistersAndAdjustStack(*this, PersistentCallerSavedRegs(), 0); | 315 | Common::X64::ABI_PushRegistersAndAdjustStack(*this, PersistentCallerSavedRegs(), 0); |
| 309 | mov(Common::X64::ABI_PARAM1, qword[STATE]); | 316 | mov(Common::X64::ABI_PARAM1, qword[STATE]); |
| @@ -435,6 +442,9 @@ void MacroJITx64Impl::Compile() { | |||
| 435 | // one if our register isn't "dirty" | 442 | // one if our register isn't "dirty" |
| 436 | optimizer.optimize_for_method_move = true; | 443 | optimizer.optimize_for_method_move = true; |
| 437 | 444 | ||
| 445 | // Enable run-time assertions in JITted code | ||
| 446 | optimizer.enable_asserts = false; | ||
| 447 | |||
| 438 | // Check to see if we can skip emitting certain instructions | 448 | // Check to see if we can skip emitting certain instructions |
| 439 | Optimizer_ScanFlags(); | 449 | Optimizer_ScanFlags(); |
| 440 | 450 | ||
diff --git a/src/video_core/macro/macro_jit_x64.h b/src/video_core/macro/macro_jit_x64.h index 51ec090b8..a180e7428 100644 --- a/src/video_core/macro/macro_jit_x64.h +++ b/src/video_core/macro/macro_jit_x64.h | |||
| @@ -76,6 +76,7 @@ private: | |||
| 76 | bool zero_reg_skip{}; | 76 | bool zero_reg_skip{}; |
| 77 | bool skip_dummy_addimmediate{}; | 77 | bool skip_dummy_addimmediate{}; |
| 78 | bool optimize_for_method_move{}; | 78 | bool optimize_for_method_move{}; |
| 79 | bool enable_asserts{}; | ||
| 79 | }; | 80 | }; |
| 80 | OptimizerState optimizer{}; | 81 | OptimizerState optimizer{}; |
| 81 | 82 | ||
diff --git a/src/video_core/renderer_opengl/maxwell_to_gl.h b/src/video_core/renderer_opengl/maxwell_to_gl.h index 994ae98eb..35e329240 100644 --- a/src/video_core/renderer_opengl/maxwell_to_gl.h +++ b/src/video_core/renderer_opengl/maxwell_to_gl.h | |||
| @@ -46,10 +46,8 @@ inline GLenum VertexType(Maxwell::VertexAttribute attrib) { | |||
| 46 | return GL_UNSIGNED_INT; | 46 | return GL_UNSIGNED_INT; |
| 47 | case Maxwell::VertexAttribute::Size::Size_10_10_10_2: | 47 | case Maxwell::VertexAttribute::Size::Size_10_10_10_2: |
| 48 | return GL_UNSIGNED_INT_2_10_10_10_REV; | 48 | return GL_UNSIGNED_INT_2_10_10_10_REV; |
| 49 | default: | ||
| 50 | LOG_ERROR(Render_OpenGL, "Unimplemented vertex size={}", attrib.SizeString()); | ||
| 51 | return {}; | ||
| 52 | } | 49 | } |
| 50 | break; | ||
| 53 | case Maxwell::VertexAttribute::Type::SignedInt: | 51 | case Maxwell::VertexAttribute::Type::SignedInt: |
| 54 | case Maxwell::VertexAttribute::Type::SignedNorm: | 52 | case Maxwell::VertexAttribute::Type::SignedNorm: |
| 55 | switch (attrib.size) { | 53 | switch (attrib.size) { |
| @@ -70,10 +68,8 @@ inline GLenum VertexType(Maxwell::VertexAttribute attrib) { | |||
| 70 | return GL_INT; | 68 | return GL_INT; |
| 71 | case Maxwell::VertexAttribute::Size::Size_10_10_10_2: | 69 | case Maxwell::VertexAttribute::Size::Size_10_10_10_2: |
| 72 | return GL_INT_2_10_10_10_REV; | 70 | return GL_INT_2_10_10_10_REV; |
| 73 | default: | ||
| 74 | LOG_ERROR(Render_OpenGL, "Unimplemented vertex size={}", attrib.SizeString()); | ||
| 75 | return {}; | ||
| 76 | } | 71 | } |
| 72 | break; | ||
| 77 | case Maxwell::VertexAttribute::Type::Float: | 73 | case Maxwell::VertexAttribute::Type::Float: |
| 78 | switch (attrib.size) { | 74 | switch (attrib.size) { |
| 79 | case Maxwell::VertexAttribute::Size::Size_16: | 75 | case Maxwell::VertexAttribute::Size::Size_16: |
| @@ -86,10 +82,8 @@ inline GLenum VertexType(Maxwell::VertexAttribute attrib) { | |||
| 86 | case Maxwell::VertexAttribute::Size::Size_32_32_32: | 82 | case Maxwell::VertexAttribute::Size::Size_32_32_32: |
| 87 | case Maxwell::VertexAttribute::Size::Size_32_32_32_32: | 83 | case Maxwell::VertexAttribute::Size::Size_32_32_32_32: |
| 88 | return GL_FLOAT; | 84 | return GL_FLOAT; |
| 89 | default: | ||
| 90 | LOG_ERROR(Render_OpenGL, "Unimplemented vertex size={}", attrib.SizeString()); | ||
| 91 | return {}; | ||
| 92 | } | 85 | } |
| 86 | break; | ||
| 93 | case Maxwell::VertexAttribute::Type::UnsignedScaled: | 87 | case Maxwell::VertexAttribute::Type::UnsignedScaled: |
| 94 | switch (attrib.size) { | 88 | switch (attrib.size) { |
| 95 | case Maxwell::VertexAttribute::Size::Size_8: | 89 | case Maxwell::VertexAttribute::Size::Size_8: |
| @@ -102,10 +96,8 @@ inline GLenum VertexType(Maxwell::VertexAttribute attrib) { | |||
| 102 | case Maxwell::VertexAttribute::Size::Size_16_16_16: | 96 | case Maxwell::VertexAttribute::Size::Size_16_16_16: |
| 103 | case Maxwell::VertexAttribute::Size::Size_16_16_16_16: | 97 | case Maxwell::VertexAttribute::Size::Size_16_16_16_16: |
| 104 | return GL_UNSIGNED_SHORT; | 98 | return GL_UNSIGNED_SHORT; |
| 105 | default: | ||
| 106 | LOG_ERROR(Render_OpenGL, "Unimplemented vertex size={}", attrib.SizeString()); | ||
| 107 | return {}; | ||
| 108 | } | 99 | } |
| 100 | break; | ||
| 109 | case Maxwell::VertexAttribute::Type::SignedScaled: | 101 | case Maxwell::VertexAttribute::Type::SignedScaled: |
| 110 | switch (attrib.size) { | 102 | switch (attrib.size) { |
| 111 | case Maxwell::VertexAttribute::Size::Size_8: | 103 | case Maxwell::VertexAttribute::Size::Size_8: |
| @@ -118,14 +110,12 @@ inline GLenum VertexType(Maxwell::VertexAttribute attrib) { | |||
| 118 | case Maxwell::VertexAttribute::Size::Size_16_16_16: | 110 | case Maxwell::VertexAttribute::Size::Size_16_16_16: |
| 119 | case Maxwell::VertexAttribute::Size::Size_16_16_16_16: | 111 | case Maxwell::VertexAttribute::Size::Size_16_16_16_16: |
| 120 | return GL_SHORT; | 112 | return GL_SHORT; |
| 121 | default: | ||
| 122 | LOG_ERROR(Render_OpenGL, "Unimplemented vertex size={}", attrib.SizeString()); | ||
| 123 | return {}; | ||
| 124 | } | 113 | } |
| 125 | default: | 114 | break; |
| 126 | LOG_ERROR(Render_OpenGL, "Unimplemented vertex type={}", attrib.TypeString()); | ||
| 127 | return {}; | ||
| 128 | } | 115 | } |
| 116 | UNIMPLEMENTED_MSG("Unimplemented vertex type={} and size={}", attrib.TypeString(), | ||
| 117 | attrib.SizeString()); | ||
| 118 | return {}; | ||
| 129 | } | 119 | } |
| 130 | 120 | ||
| 131 | inline GLenum IndexFormat(Maxwell::IndexFormat index_format) { | 121 | inline GLenum IndexFormat(Maxwell::IndexFormat index_format) { |
| @@ -137,8 +127,7 @@ inline GLenum IndexFormat(Maxwell::IndexFormat index_format) { | |||
| 137 | case Maxwell::IndexFormat::UnsignedInt: | 127 | case Maxwell::IndexFormat::UnsignedInt: |
| 138 | return GL_UNSIGNED_INT; | 128 | return GL_UNSIGNED_INT; |
| 139 | } | 129 | } |
| 140 | LOG_CRITICAL(Render_OpenGL, "Unimplemented index_format={}", static_cast<u32>(index_format)); | 130 | UNREACHABLE_MSG("Invalid index_format={}", static_cast<u32>(index_format)); |
| 141 | UNREACHABLE(); | ||
| 142 | return {}; | 131 | return {}; |
| 143 | } | 132 | } |
| 144 | 133 | ||
| @@ -180,33 +169,32 @@ inline GLenum PrimitiveTopology(Maxwell::PrimitiveTopology topology) { | |||
| 180 | } | 169 | } |
| 181 | 170 | ||
| 182 | inline GLenum TextureFilterMode(Tegra::Texture::TextureFilter filter_mode, | 171 | inline GLenum TextureFilterMode(Tegra::Texture::TextureFilter filter_mode, |
| 183 | Tegra::Texture::TextureMipmapFilter mip_filter_mode) { | 172 | Tegra::Texture::TextureMipmapFilter mipmap_filter_mode) { |
| 184 | switch (filter_mode) { | 173 | switch (filter_mode) { |
| 185 | case Tegra::Texture::TextureFilter::Linear: { | 174 | case Tegra::Texture::TextureFilter::Nearest: |
| 186 | switch (mip_filter_mode) { | 175 | switch (mipmap_filter_mode) { |
| 187 | case Tegra::Texture::TextureMipmapFilter::None: | 176 | case Tegra::Texture::TextureMipmapFilter::None: |
| 188 | return GL_LINEAR; | 177 | return GL_NEAREST; |
| 189 | case Tegra::Texture::TextureMipmapFilter::Nearest: | 178 | case Tegra::Texture::TextureMipmapFilter::Nearest: |
| 190 | return GL_LINEAR_MIPMAP_NEAREST; | 179 | return GL_NEAREST_MIPMAP_NEAREST; |
| 191 | case Tegra::Texture::TextureMipmapFilter::Linear: | 180 | case Tegra::Texture::TextureMipmapFilter::Linear: |
| 192 | return GL_LINEAR_MIPMAP_LINEAR; | 181 | return GL_NEAREST_MIPMAP_LINEAR; |
| 193 | } | 182 | } |
| 194 | break; | 183 | break; |
| 195 | } | 184 | case Tegra::Texture::TextureFilter::Linear: |
| 196 | case Tegra::Texture::TextureFilter::Nearest: { | 185 | switch (mipmap_filter_mode) { |
| 197 | switch (mip_filter_mode) { | ||
| 198 | case Tegra::Texture::TextureMipmapFilter::None: | 186 | case Tegra::Texture::TextureMipmapFilter::None: |
| 199 | return GL_NEAREST; | 187 | return GL_LINEAR; |
| 200 | case Tegra::Texture::TextureMipmapFilter::Nearest: | 188 | case Tegra::Texture::TextureMipmapFilter::Nearest: |
| 201 | return GL_NEAREST_MIPMAP_NEAREST; | 189 | return GL_LINEAR_MIPMAP_NEAREST; |
| 202 | case Tegra::Texture::TextureMipmapFilter::Linear: | 190 | case Tegra::Texture::TextureMipmapFilter::Linear: |
| 203 | return GL_NEAREST_MIPMAP_LINEAR; | 191 | return GL_LINEAR_MIPMAP_LINEAR; |
| 204 | } | 192 | } |
| 205 | break; | 193 | break; |
| 206 | } | 194 | } |
| 207 | } | 195 | UNREACHABLE_MSG("Invalid texture filter mode={} and mipmap filter mode={}", |
| 208 | LOG_ERROR(Render_OpenGL, "Unimplemented texture filter mode={}", static_cast<u32>(filter_mode)); | 196 | static_cast<u32>(filter_mode), static_cast<u32>(mipmap_filter_mode)); |
| 209 | return GL_LINEAR; | 197 | return GL_NEAREST; |
| 210 | } | 198 | } |
| 211 | 199 | ||
| 212 | inline GLenum WrapMode(Tegra::Texture::WrapMode wrap_mode) { | 200 | inline GLenum WrapMode(Tegra::Texture::WrapMode wrap_mode) { |
| @@ -229,10 +217,9 @@ inline GLenum WrapMode(Tegra::Texture::WrapMode wrap_mode) { | |||
| 229 | } else { | 217 | } else { |
| 230 | return GL_MIRROR_CLAMP_TO_EDGE; | 218 | return GL_MIRROR_CLAMP_TO_EDGE; |
| 231 | } | 219 | } |
| 232 | default: | ||
| 233 | LOG_ERROR(Render_OpenGL, "Unimplemented texture wrap mode={}", static_cast<u32>(wrap_mode)); | ||
| 234 | return GL_REPEAT; | ||
| 235 | } | 220 | } |
| 221 | UNIMPLEMENTED_MSG("Unimplemented texture wrap mode={}", static_cast<u32>(wrap_mode)); | ||
| 222 | return GL_REPEAT; | ||
| 236 | } | 223 | } |
| 237 | 224 | ||
| 238 | inline GLenum DepthCompareFunc(Tegra::Texture::DepthCompareFunc func) { | 225 | inline GLenum DepthCompareFunc(Tegra::Texture::DepthCompareFunc func) { |
| @@ -254,8 +241,7 @@ inline GLenum DepthCompareFunc(Tegra::Texture::DepthCompareFunc func) { | |||
| 254 | case Tegra::Texture::DepthCompareFunc::Always: | 241 | case Tegra::Texture::DepthCompareFunc::Always: |
| 255 | return GL_ALWAYS; | 242 | return GL_ALWAYS; |
| 256 | } | 243 | } |
| 257 | LOG_ERROR(Render_OpenGL, "Unimplemented texture depth compare function ={}", | 244 | UNIMPLEMENTED_MSG("Unimplemented texture depth compare function={}", static_cast<u32>(func)); |
| 258 | static_cast<u32>(func)); | ||
| 259 | return GL_GREATER; | 245 | return GL_GREATER; |
| 260 | } | 246 | } |
| 261 | 247 | ||
| @@ -277,7 +263,7 @@ inline GLenum BlendEquation(Maxwell::Blend::Equation equation) { | |||
| 277 | case Maxwell::Blend::Equation::MaxGL: | 263 | case Maxwell::Blend::Equation::MaxGL: |
| 278 | return GL_MAX; | 264 | return GL_MAX; |
| 279 | } | 265 | } |
| 280 | LOG_ERROR(Render_OpenGL, "Unimplemented blend equation={}", static_cast<u32>(equation)); | 266 | UNIMPLEMENTED_MSG("Unimplemented blend equation={}", static_cast<u32>(equation)); |
| 281 | return GL_FUNC_ADD; | 267 | return GL_FUNC_ADD; |
| 282 | } | 268 | } |
| 283 | 269 | ||
| @@ -341,7 +327,7 @@ inline GLenum BlendFunc(Maxwell::Blend::Factor factor) { | |||
| 341 | case Maxwell::Blend::Factor::OneMinusConstantAlphaGL: | 327 | case Maxwell::Blend::Factor::OneMinusConstantAlphaGL: |
| 342 | return GL_ONE_MINUS_CONSTANT_ALPHA; | 328 | return GL_ONE_MINUS_CONSTANT_ALPHA; |
| 343 | } | 329 | } |
| 344 | LOG_ERROR(Render_OpenGL, "Unimplemented blend factor={}", static_cast<u32>(factor)); | 330 | UNIMPLEMENTED_MSG("Unimplemented blend factor={}", static_cast<u32>(factor)); |
| 345 | return GL_ZERO; | 331 | return GL_ZERO; |
| 346 | } | 332 | } |
| 347 | 333 | ||
| @@ -361,7 +347,7 @@ inline GLenum SwizzleSource(Tegra::Texture::SwizzleSource source) { | |||
| 361 | case Tegra::Texture::SwizzleSource::OneFloat: | 347 | case Tegra::Texture::SwizzleSource::OneFloat: |
| 362 | return GL_ONE; | 348 | return GL_ONE; |
| 363 | } | 349 | } |
| 364 | LOG_ERROR(Render_OpenGL, "Unimplemented swizzle source={}", static_cast<u32>(source)); | 350 | UNIMPLEMENTED_MSG("Unimplemented swizzle source={}", static_cast<u32>(source)); |
| 365 | return GL_ZERO; | 351 | return GL_ZERO; |
| 366 | } | 352 | } |
| 367 | 353 | ||
| @@ -392,7 +378,7 @@ inline GLenum ComparisonOp(Maxwell::ComparisonOp comparison) { | |||
| 392 | case Maxwell::ComparisonOp::AlwaysOld: | 378 | case Maxwell::ComparisonOp::AlwaysOld: |
| 393 | return GL_ALWAYS; | 379 | return GL_ALWAYS; |
| 394 | } | 380 | } |
| 395 | LOG_ERROR(Render_OpenGL, "Unimplemented comparison op={}", static_cast<u32>(comparison)); | 381 | UNIMPLEMENTED_MSG("Unimplemented comparison op={}", static_cast<u32>(comparison)); |
| 396 | return GL_ALWAYS; | 382 | return GL_ALWAYS; |
| 397 | } | 383 | } |
| 398 | 384 | ||
| @@ -423,7 +409,7 @@ inline GLenum StencilOp(Maxwell::StencilOp stencil) { | |||
| 423 | case Maxwell::StencilOp::DecrWrapOGL: | 409 | case Maxwell::StencilOp::DecrWrapOGL: |
| 424 | return GL_DECR_WRAP; | 410 | return GL_DECR_WRAP; |
| 425 | } | 411 | } |
| 426 | LOG_ERROR(Render_OpenGL, "Unimplemented stencil op={}", static_cast<u32>(stencil)); | 412 | UNIMPLEMENTED_MSG("Unimplemented stencil op={}", static_cast<u32>(stencil)); |
| 427 | return GL_KEEP; | 413 | return GL_KEEP; |
| 428 | } | 414 | } |
| 429 | 415 | ||
| @@ -434,7 +420,7 @@ inline GLenum FrontFace(Maxwell::FrontFace front_face) { | |||
| 434 | case Maxwell::FrontFace::CounterClockWise: | 420 | case Maxwell::FrontFace::CounterClockWise: |
| 435 | return GL_CCW; | 421 | return GL_CCW; |
| 436 | } | 422 | } |
| 437 | LOG_ERROR(Render_OpenGL, "Unimplemented front face cull={}", static_cast<u32>(front_face)); | 423 | UNIMPLEMENTED_MSG("Unimplemented front face cull={}", static_cast<u32>(front_face)); |
| 438 | return GL_CCW; | 424 | return GL_CCW; |
| 439 | } | 425 | } |
| 440 | 426 | ||
| @@ -447,7 +433,7 @@ inline GLenum CullFace(Maxwell::CullFace cull_face) { | |||
| 447 | case Maxwell::CullFace::FrontAndBack: | 433 | case Maxwell::CullFace::FrontAndBack: |
| 448 | return GL_FRONT_AND_BACK; | 434 | return GL_FRONT_AND_BACK; |
| 449 | } | 435 | } |
| 450 | LOG_ERROR(Render_OpenGL, "Unimplemented cull face={}", static_cast<u32>(cull_face)); | 436 | UNIMPLEMENTED_MSG("Unimplemented cull face={}", static_cast<u32>(cull_face)); |
| 451 | return GL_BACK; | 437 | return GL_BACK; |
| 452 | } | 438 | } |
| 453 | 439 | ||
| @@ -486,7 +472,7 @@ inline GLenum LogicOp(Maxwell::LogicOperation operation) { | |||
| 486 | case Maxwell::LogicOperation::Set: | 472 | case Maxwell::LogicOperation::Set: |
| 487 | return GL_SET; | 473 | return GL_SET; |
| 488 | } | 474 | } |
| 489 | LOG_ERROR(Render_OpenGL, "Unimplemented logic operation={}", static_cast<u32>(operation)); | 475 | UNIMPLEMENTED_MSG("Unimplemented logic operation={}", static_cast<u32>(operation)); |
| 490 | return GL_COPY; | 476 | return GL_COPY; |
| 491 | } | 477 | } |
| 492 | 478 | ||
diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp index 62e950d31..1f2b6734b 100644 --- a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp +++ b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp | |||
| @@ -21,29 +21,29 @@ namespace Sampler { | |||
| 21 | 21 | ||
| 22 | VkFilter Filter(Tegra::Texture::TextureFilter filter) { | 22 | VkFilter Filter(Tegra::Texture::TextureFilter filter) { |
| 23 | switch (filter) { | 23 | switch (filter) { |
| 24 | case Tegra::Texture::TextureFilter::Linear: | ||
| 25 | return VK_FILTER_LINEAR; | ||
| 26 | case Tegra::Texture::TextureFilter::Nearest: | 24 | case Tegra::Texture::TextureFilter::Nearest: |
| 27 | return VK_FILTER_NEAREST; | 25 | return VK_FILTER_NEAREST; |
| 26 | case Tegra::Texture::TextureFilter::Linear: | ||
| 27 | return VK_FILTER_LINEAR; | ||
| 28 | } | 28 | } |
| 29 | UNIMPLEMENTED_MSG("Unimplemented sampler filter={}", static_cast<u32>(filter)); | 29 | UNREACHABLE_MSG("Invalid sampler filter={}", static_cast<u32>(filter)); |
| 30 | return {}; | 30 | return {}; |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | VkSamplerMipmapMode MipmapMode(Tegra::Texture::TextureMipmapFilter mipmap_filter) { | 33 | VkSamplerMipmapMode MipmapMode(Tegra::Texture::TextureMipmapFilter mipmap_filter) { |
| 34 | switch (mipmap_filter) { | 34 | switch (mipmap_filter) { |
| 35 | case Tegra::Texture::TextureMipmapFilter::None: | 35 | case Tegra::Texture::TextureMipmapFilter::None: |
| 36 | // TODO(Rodrigo): None seems to be mapped to OpenGL's mag and min filters without mipmapping | 36 | // There are no Vulkan filter modes that directly correspond to OpenGL minification filters |
| 37 | // (e.g. GL_NEAREST and GL_LINEAR). Vulkan doesn't have such a thing, find out if we have to | 37 | // of GL_LINEAR or GL_NEAREST, but they can be emulated using |
| 38 | // use an image view with a single mipmap level to emulate this. | 38 | // VK_SAMPLER_MIPMAP_MODE_NEAREST, minLod = 0, and maxLod = 0.25, and using minFilter = |
| 39 | return VK_SAMPLER_MIPMAP_MODE_LINEAR; | 39 | // VK_FILTER_LINEAR or minFilter = VK_FILTER_NEAREST, respectively. |
| 40 | ; | 40 | return VK_SAMPLER_MIPMAP_MODE_NEAREST; |
| 41 | case Tegra::Texture::TextureMipmapFilter::Linear: | ||
| 42 | return VK_SAMPLER_MIPMAP_MODE_LINEAR; | ||
| 43 | case Tegra::Texture::TextureMipmapFilter::Nearest: | 41 | case Tegra::Texture::TextureMipmapFilter::Nearest: |
| 44 | return VK_SAMPLER_MIPMAP_MODE_NEAREST; | 42 | return VK_SAMPLER_MIPMAP_MODE_NEAREST; |
| 43 | case Tegra::Texture::TextureMipmapFilter::Linear: | ||
| 44 | return VK_SAMPLER_MIPMAP_MODE_LINEAR; | ||
| 45 | } | 45 | } |
| 46 | UNIMPLEMENTED_MSG("Unimplemented sampler mipmap mode={}", static_cast<u32>(mipmap_filter)); | 46 | UNREACHABLE_MSG("Invalid sampler mipmap mode={}", static_cast<u32>(mipmap_filter)); |
| 47 | return {}; | 47 | return {}; |
| 48 | } | 48 | } |
| 49 | 49 | ||
| @@ -78,10 +78,9 @@ VkSamplerAddressMode WrapMode(const VKDevice& device, Tegra::Texture::WrapMode w | |||
| 78 | case Tegra::Texture::WrapMode::MirrorOnceBorder: | 78 | case Tegra::Texture::WrapMode::MirrorOnceBorder: |
| 79 | UNIMPLEMENTED(); | 79 | UNIMPLEMENTED(); |
| 80 | return VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE; | 80 | return VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE; |
| 81 | default: | ||
| 82 | UNIMPLEMENTED_MSG("Unimplemented wrap mode={}", static_cast<u32>(wrap_mode)); | ||
| 83 | return {}; | ||
| 84 | } | 81 | } |
| 82 | UNIMPLEMENTED_MSG("Unimplemented wrap mode={}", static_cast<u32>(wrap_mode)); | ||
| 83 | return {}; | ||
| 85 | } | 84 | } |
| 86 | 85 | ||
| 87 | VkCompareOp DepthCompareFunction(Tegra::Texture::DepthCompareFunc depth_compare_func) { | 86 | VkCompareOp DepthCompareFunction(Tegra::Texture::DepthCompareFunc depth_compare_func) { |
| @@ -288,10 +287,9 @@ VkPrimitiveTopology PrimitiveTopology([[maybe_unused]] const VKDevice& device, | |||
| 288 | return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; | 287 | return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; |
| 289 | case Maxwell::PrimitiveTopology::Patches: | 288 | case Maxwell::PrimitiveTopology::Patches: |
| 290 | return VK_PRIMITIVE_TOPOLOGY_PATCH_LIST; | 289 | return VK_PRIMITIVE_TOPOLOGY_PATCH_LIST; |
| 291 | default: | ||
| 292 | UNIMPLEMENTED_MSG("Unimplemented topology={}", static_cast<u32>(topology)); | ||
| 293 | return {}; | ||
| 294 | } | 290 | } |
| 291 | UNIMPLEMENTED_MSG("Unimplemented topology={}", static_cast<u32>(topology)); | ||
| 292 | return {}; | ||
| 295 | } | 293 | } |
| 296 | 294 | ||
| 297 | VkFormat VertexFormat(Maxwell::VertexAttribute::Type type, Maxwell::VertexAttribute::Size size) { | 295 | VkFormat VertexFormat(Maxwell::VertexAttribute::Type type, Maxwell::VertexAttribute::Size size) { |
diff --git a/src/video_core/renderer_vulkan/vk_sampler_cache.cpp b/src/video_core/renderer_vulkan/vk_sampler_cache.cpp index e6f2fa553..616eacc36 100644 --- a/src/video_core/renderer_vulkan/vk_sampler_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_sampler_cache.cpp | |||
| @@ -9,6 +9,8 @@ | |||
| 9 | #include "video_core/renderer_vulkan/wrapper.h" | 9 | #include "video_core/renderer_vulkan/wrapper.h" |
| 10 | #include "video_core/textures/texture.h" | 10 | #include "video_core/textures/texture.h" |
| 11 | 11 | ||
| 12 | using Tegra::Texture::TextureMipmapFilter; | ||
| 13 | |||
| 12 | namespace Vulkan { | 14 | namespace Vulkan { |
| 13 | 15 | ||
| 14 | namespace { | 16 | namespace { |
| @@ -63,8 +65,8 @@ vk::Sampler VKSamplerCache::CreateSampler(const Tegra::Texture::TSCEntry& tsc) c | |||
| 63 | ci.maxAnisotropy = tsc.GetMaxAnisotropy(); | 65 | ci.maxAnisotropy = tsc.GetMaxAnisotropy(); |
| 64 | ci.compareEnable = tsc.depth_compare_enabled; | 66 | ci.compareEnable = tsc.depth_compare_enabled; |
| 65 | ci.compareOp = MaxwellToVK::Sampler::DepthCompareFunction(tsc.depth_compare_func); | 67 | ci.compareOp = MaxwellToVK::Sampler::DepthCompareFunction(tsc.depth_compare_func); |
| 66 | ci.minLod = tsc.GetMinLod(); | 68 | ci.minLod = tsc.mipmap_filter == TextureMipmapFilter::None ? 0.0f : tsc.GetMinLod(); |
| 67 | ci.maxLod = tsc.GetMaxLod(); | 69 | ci.maxLod = tsc.mipmap_filter == TextureMipmapFilter::None ? 0.25f : tsc.GetMaxLod(); |
| 68 | ci.borderColor = arbitrary_borders ? VK_BORDER_COLOR_INT_CUSTOM_EXT : ConvertBorderColor(color); | 70 | ci.borderColor = arbitrary_borders ? VK_BORDER_COLOR_INT_CUSTOM_EXT : ConvertBorderColor(color); |
| 69 | ci.unnormalizedCoordinates = VK_FALSE; | 71 | ci.unnormalizedCoordinates = VK_FALSE; |
| 70 | return device.GetLogical().CreateSampler(ci); | 72 | return device.GetLogical().CreateSampler(ci); |
diff --git a/src/yuzu/configuration/configure_service.cpp b/src/yuzu/configuration/configure_service.cpp index 06566e981..0de7a4f0b 100644 --- a/src/yuzu/configuration/configure_service.cpp +++ b/src/yuzu/configuration/configure_service.cpp | |||
| @@ -68,6 +68,7 @@ void ConfigureService::SetConfiguration() { | |||
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | std::pair<QString, QString> ConfigureService::BCATDownloadEvents() { | 70 | std::pair<QString, QString> ConfigureService::BCATDownloadEvents() { |
| 71 | #ifdef YUZU_ENABLE_BOXCAT | ||
| 71 | std::optional<std::string> global; | 72 | std::optional<std::string> global; |
| 72 | std::map<std::string, Service::BCAT::EventStatus> map; | 73 | std::map<std::string, Service::BCAT::EventStatus> map; |
| 73 | const auto res = Service::BCAT::Boxcat::GetStatus(global, map); | 74 | const auto res = Service::BCAT::Boxcat::GetStatus(global, map); |
| @@ -105,7 +106,10 @@ std::pair<QString, QString> ConfigureService::BCATDownloadEvents() { | |||
| 105 | .arg(QString::fromStdString(key)) | 106 | .arg(QString::fromStdString(key)) |
| 106 | .arg(FormatEventStatusString(value)); | 107 | .arg(FormatEventStatusString(value)); |
| 107 | } | 108 | } |
| 108 | return {QStringLiteral("Current Boxcat Events"), std::move(out)}; | 109 | return {tr("Current Boxcat Events"), std::move(out)}; |
| 110 | #else | ||
| 111 | return {tr("Current Boxcat Events"), tr("There are currently no events on boxcat.")}; | ||
| 112 | #endif | ||
| 109 | } | 113 | } |
| 110 | 114 | ||
| 111 | void ConfigureService::OnBCATImplChanged() { | 115 | void ConfigureService::OnBCATImplChanged() { |