summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/audio_core/audio_out.cpp3
-rw-r--r--src/audio_core/audio_renderer.cpp6
-rw-r--r--src/audio_core/stream.cpp7
-rw-r--r--src/core/CMakeLists.txt1
-rw-r--r--src/core/arm/arm_interface.cpp26
-rw-r--r--src/core/arm/arm_interface.h8
-rw-r--r--src/core/arm/unicorn/arm_unicorn.cpp1
-rw-r--r--src/core/file_sys/program_metadata.cpp10
-rw-r--r--src/core/hle/kernel/process.cpp16
-rw-r--r--src/core/hle/kernel/process.h9
-rw-r--r--src/core/hle/kernel/svc.cpp35
-rw-r--r--src/core/hle/service/fatal/fatal.cpp3
-rw-r--r--src/core/hle/service/ldr/ldr.cpp27
-rw-r--r--src/core/hle/service/time/time.cpp20
-rw-r--r--src/core/hle/service/time/time.h12
-rw-r--r--src/video_core/morton.cpp4
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp22
-rw-r--r--src/video_core/surface.cpp7
-rw-r--r--src/video_core/surface.h92
19 files changed, 153 insertions, 156 deletions
diff --git a/src/audio_core/audio_out.cpp b/src/audio_core/audio_out.cpp
index cbba17632..50d2a1ed3 100644
--- a/src/audio_core/audio_out.cpp
+++ b/src/audio_core/audio_out.cpp
@@ -22,8 +22,7 @@ static Stream::Format ChannelsToStreamFormat(u32 num_channels) {
return Stream::Format::Multi51Channel16;
}
- LOG_CRITICAL(Audio, "Unimplemented num_channels={}", num_channels);
- UNREACHABLE();
+ UNIMPLEMENTED_MSG("Unimplemented num_channels={}", num_channels);
return {};
}
diff --git a/src/audio_core/audio_renderer.cpp b/src/audio_core/audio_renderer.cpp
index 2683f3a5f..00c026511 100644
--- a/src/audio_core/audio_renderer.cpp
+++ b/src/audio_core/audio_renderer.cpp
@@ -260,8 +260,7 @@ void AudioRenderer::VoiceState::RefreshBuffer() {
break;
}
default:
- LOG_CRITICAL(Audio, "Unimplemented sample_format={}", info.sample_format);
- UNREACHABLE();
+ UNIMPLEMENTED_MSG("Unimplemented sample_format={}", info.sample_format);
break;
}
@@ -280,8 +279,7 @@ void AudioRenderer::VoiceState::RefreshBuffer() {
break;
}
default:
- LOG_CRITICAL(Audio, "Unimplemented channel_count={}", info.channel_count);
- UNREACHABLE();
+ UNIMPLEMENTED_MSG("Unimplemented channel_count={}", info.channel_count);
break;
}
diff --git a/src/audio_core/stream.cpp b/src/audio_core/stream.cpp
index f35628e45..874673c4e 100644
--- a/src/audio_core/stream.cpp
+++ b/src/audio_core/stream.cpp
@@ -28,8 +28,7 @@ u32 Stream::GetNumChannels() const {
case Format::Multi51Channel16:
return 6;
}
- LOG_CRITICAL(Audio, "Unimplemented format={}", static_cast<u32>(format));
- UNREACHABLE();
+ UNIMPLEMENTED_MSG("Unimplemented format={}", static_cast<u32>(format));
return {};
}
@@ -49,7 +48,7 @@ void Stream::Play() {
void Stream::Stop() {
state = State::Stopped;
- ASSERT_MSG(false, "Unimplemented");
+ UNIMPLEMENTED();
}
Stream::State Stream::GetState() const {
@@ -120,7 +119,7 @@ bool Stream::QueueBuffer(BufferPtr&& buffer) {
}
bool Stream::ContainsBuffer(Buffer::Tag tag) const {
- ASSERT_MSG(false, "Unimplemented");
+ UNIMPLEMENTED();
return {};
}
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index f38271336..8f2db5bea 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -1,5 +1,6 @@
add_library(core STATIC
arm/arm_interface.h
+ arm/arm_interface.cpp
arm/exclusive_monitor.cpp
arm/exclusive_monitor.h
arm/unicorn/arm_unicorn.cpp
diff --git a/src/core/arm/arm_interface.cpp b/src/core/arm/arm_interface.cpp
new file mode 100644
index 000000000..bcc812da4
--- /dev/null
+++ b/src/core/arm/arm_interface.cpp
@@ -0,0 +1,26 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "arm_interface.h"
+#include "common/common_types.h"
+#include "common/logging/log.h"
+#include "core/memory.h"
+
+namespace Core {
+void ARM_Interface::LogBacktrace() {
+ VAddr fp = GetReg(29);
+ VAddr lr = GetReg(30);
+ VAddr sp = GetReg(13);
+ VAddr pc = GetPC();
+ LOG_ERROR(Core_ARM, "Backtrace, sp={:016X}, pc={:016X}", sp, pc);
+ for (;;) {
+ LOG_ERROR(Core_ARM, "{:016X}", lr);
+ if (!fp) {
+ break;
+ }
+ lr = Memory::Read64(fp + 8) - 4;
+ fp = Memory::Read64(fp);
+ }
+}
+}; // namespace Core
diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h
index 59da33f30..91d2b0f81 100644
--- a/src/core/arm/arm_interface.h
+++ b/src/core/arm/arm_interface.h
@@ -141,6 +141,14 @@ public:
/// Prepare core for thread reschedule (if needed to correctly handle state)
virtual void PrepareReschedule() = 0;
+
+ /// fp (= r29) points to the last frame record.
+ /// Note that this is the frame record for the *previous* frame, not the current one.
+ /// Note we need to subtract 4 from our last read to get the proper address
+ /// Frame records are two words long:
+ /// fp+0 : pointer to previous frame record
+ /// fp+8 : value of lr for frame
+ void LogBacktrace();
};
} // namespace Core
diff --git a/src/core/arm/unicorn/arm_unicorn.cpp b/src/core/arm/unicorn/arm_unicorn.cpp
index ded4dd359..c455c81fb 100644
--- a/src/core/arm/unicorn/arm_unicorn.cpp
+++ b/src/core/arm/unicorn/arm_unicorn.cpp
@@ -10,6 +10,7 @@
#include "core/core.h"
#include "core/core_timing.h"
#include "core/hle/kernel/svc.h"
+#include "core/memory.h"
namespace Core {
diff --git a/src/core/file_sys/program_metadata.cpp b/src/core/file_sys/program_metadata.cpp
index e90c8c2de..d3e00437f 100644
--- a/src/core/file_sys/program_metadata.cpp
+++ b/src/core/file_sys/program_metadata.cpp
@@ -92,16 +92,20 @@ void ProgramMetadata::Print() const {
LOG_DEBUG(Service_FS, " > 64-bit instructions: {}",
npdm_header.has_64_bit_instructions ? "YES" : "NO");
- auto address_space = "Unknown";
+ const char* address_space = "Unknown";
switch (npdm_header.address_space_type) {
case ProgramAddressSpaceType::Is36Bit:
+ address_space = "64-bit (36-bit address space)";
+ break;
case ProgramAddressSpaceType::Is39Bit:
- address_space = "64-bit";
+ address_space = "64-bit (39-bit address space)";
break;
case ProgramAddressSpaceType::Is32Bit:
- case ProgramAddressSpaceType::Is32BitNoMap:
address_space = "32-bit";
break;
+ case ProgramAddressSpaceType::Is32BitNoMap:
+ address_space = "32-bit (no map region)";
+ break;
}
LOG_DEBUG(Service_FS, " > Address space: {}\n", address_space);
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index d5ca235b0..c5aa19afa 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -227,22 +227,6 @@ void Process::LoadModule(CodeSet module_, VAddr base_addr) {
Core::System::GetInstance().ArmInterface(3).ClearInstructionCache();
}
-ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission perms) {
- return vm_manager.HeapAllocate(target, size, perms);
-}
-
-ResultCode Process::HeapFree(VAddr target, u32 size) {
- return vm_manager.HeapFree(target, size);
-}
-
-ResultCode Process::MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size, MemoryState state) {
- return vm_manager.MirrorMemory(dst_addr, src_addr, size, state);
-}
-
-ResultCode Process::UnmapMemory(VAddr dst_addr, VAddr /*src_addr*/, u64 size) {
- return vm_manager.UnmapRange(dst_addr, size);
-}
-
Kernel::Process::Process(KernelCore& kernel) : WaitObject{kernel} {}
Kernel::Process::~Process() {}
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h
index ce7d143de..450dc6eeb 100644
--- a/src/core/hle/kernel/process.h
+++ b/src/core/hle/kernel/process.h
@@ -242,7 +242,7 @@ public:
void LoadModule(CodeSet module_, VAddr base_addr);
///////////////////////////////////////////////////////////////////////////////////////////////
- // Memory Management
+ // Thread-local storage management
// Marks the next available region as used and returns the address of the slot.
VAddr MarkNextAvailableTLSSlotAsUsed(Thread& thread);
@@ -250,13 +250,6 @@ public:
// Frees a used TLS slot identified by the given address
void FreeTLSSlot(VAddr tls_address);
- ResultVal<VAddr> HeapAllocate(VAddr target, u64 size, VMAPermission perms);
- ResultCode HeapFree(VAddr target, u32 size);
-
- ResultCode MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size, MemoryState state);
-
- ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size);
-
private:
explicit Process(KernelCore& kernel);
~Process() override;
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 18fb3c44d..660e6f577 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -190,10 +190,16 @@ static ResultCode SetHeapSize(VAddr* heap_addr, u64 heap_size) {
return ERR_INVALID_SIZE;
}
- auto& process = *Core::CurrentProcess();
- const VAddr heap_base = process.VMManager().GetHeapRegionBaseAddress();
- CASCADE_RESULT(*heap_addr,
- process.HeapAllocate(heap_base, heap_size, VMAPermission::ReadWrite));
+ auto& vm_manager = Core::CurrentProcess()->VMManager();
+ const VAddr heap_base = vm_manager.GetHeapRegionBaseAddress();
+ const auto alloc_result =
+ vm_manager.HeapAllocate(heap_base, heap_size, VMAPermission::ReadWrite);
+
+ if (alloc_result.Failed()) {
+ return alloc_result.Code();
+ }
+
+ *heap_addr = *alloc_result;
return RESULT_SUCCESS;
}
@@ -307,15 +313,14 @@ static ResultCode MapMemory(VAddr dst_addr, VAddr src_addr, u64 size) {
LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr,
src_addr, size);
- auto* const current_process = Core::CurrentProcess();
- const auto& vm_manager = current_process->VMManager();
-
+ auto& vm_manager = Core::CurrentProcess()->VMManager();
const auto result = MapUnmapMemorySanityChecks(vm_manager, dst_addr, src_addr, size);
- if (result != RESULT_SUCCESS) {
+
+ if (result.IsError()) {
return result;
}
- return current_process->MirrorMemory(dst_addr, src_addr, size, MemoryState::Stack);
+ return vm_manager.MirrorMemory(dst_addr, src_addr, size, MemoryState::Stack);
}
/// Unmaps a region that was previously mapped with svcMapMemory
@@ -323,15 +328,14 @@ static ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size) {
LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr,
src_addr, size);
- auto* const current_process = Core::CurrentProcess();
- const auto& vm_manager = current_process->VMManager();
-
+ auto& vm_manager = Core::CurrentProcess()->VMManager();
const auto result = MapUnmapMemorySanityChecks(vm_manager, dst_addr, src_addr, size);
- if (result != RESULT_SUCCESS) {
+
+ if (result.IsError()) {
return result;
}
- return current_process->UnmapMemory(dst_addr, src_addr, size);
+ return vm_manager.UnmapRange(dst_addr, size);
}
/// Connect to an OS service given the port name, returns the handle to the port to out
@@ -680,6 +684,9 @@ static void Break(u32 reason, u64 info1, u64 info2) {
"Emulated program broke execution! reason=0x{:016X}, info1=0x{:016X}, info2=0x{:016X}",
reason, info1, info2);
handle_debug_buffer(info1, info2);
+ Core::System::GetInstance()
+ .ArmInterface(static_cast<std::size_t>(GetCurrentThread()->GetProcessorID()))
+ .LogBacktrace();
ASSERT(false);
Core::CurrentProcess()->PrepareForTermination();
diff --git a/src/core/hle/service/fatal/fatal.cpp b/src/core/hle/service/fatal/fatal.cpp
index 2f15ac2a6..770590d0b 100644
--- a/src/core/hle/service/fatal/fatal.cpp
+++ b/src/core/hle/service/fatal/fatal.cpp
@@ -111,7 +111,8 @@ static void GenerateErrorReport(ResultCode error_code, const FatalInfo& info) {
}
static void ThrowFatalError(ResultCode error_code, FatalType fatal_type, const FatalInfo& info) {
- LOG_ERROR(Service_Fatal, "Threw fatal error type {}", static_cast<u32>(fatal_type));
+ LOG_ERROR(Service_Fatal, "Threw fatal error type {} with error code 0x{:X}",
+ static_cast<u32>(fatal_type), error_code.raw);
switch (fatal_type) {
case FatalType::ErrorReportAndScreen:
GenerateErrorReport(error_code, info);
diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp
index 13bcefe07..9df7ac50f 100644
--- a/src/core/hle/service/ldr/ldr.cpp
+++ b/src/core/hle/service/ldr/ldr.cpp
@@ -318,14 +318,18 @@ public:
return;
}
- ASSERT(process->MirrorMemory(*map_address, nro_addr, nro_size,
- Kernel::MemoryState::ModuleCodeStatic) == RESULT_SUCCESS);
- ASSERT(process->UnmapMemory(nro_addr, 0, nro_size) == RESULT_SUCCESS);
+ ASSERT(vm_manager
+ .MirrorMemory(*map_address, nro_addr, nro_size,
+ Kernel::MemoryState::ModuleCodeStatic)
+ .IsSuccess());
+ ASSERT(vm_manager.UnmapRange(nro_addr, nro_size).IsSuccess());
if (bss_size > 0) {
- ASSERT(process->MirrorMemory(*map_address + nro_size, bss_addr, bss_size,
- Kernel::MemoryState::ModuleCodeStatic) == RESULT_SUCCESS);
- ASSERT(process->UnmapMemory(bss_addr, 0, bss_size) == RESULT_SUCCESS);
+ ASSERT(vm_manager
+ .MirrorMemory(*map_address + nro_size, bss_addr, bss_size,
+ Kernel::MemoryState::ModuleCodeStatic)
+ .IsSuccess());
+ ASSERT(vm_manager.UnmapRange(bss_addr, bss_size).IsSuccess());
}
vm_manager.ReprotectRange(*map_address, header.text_size,
@@ -380,13 +384,14 @@ public:
return;
}
- auto* process = Core::CurrentProcess();
- auto& vm_manager = process->VMManager();
+ auto& vm_manager = Core::CurrentProcess()->VMManager();
const auto& nro_size = iter->second.size;
- ASSERT(process->MirrorMemory(heap_addr, mapped_addr, nro_size,
- Kernel::MemoryState::ModuleCodeStatic) == RESULT_SUCCESS);
- ASSERT(process->UnmapMemory(mapped_addr, 0, nro_size) == RESULT_SUCCESS);
+ ASSERT(vm_manager
+ .MirrorMemory(heap_addr, mapped_addr, nro_size,
+ Kernel::MemoryState::ModuleCodeStatic)
+ .IsSuccess());
+ ASSERT(vm_manager.UnmapRange(mapped_addr, nro_size).IsSuccess());
Core::System::GetInstance().InvalidateCpuInstructionCaches();
diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp
index 60b201d06..16564de24 100644
--- a/src/core/hle/service/time/time.cpp
+++ b/src/core/hle/service/time/time.cpp
@@ -264,14 +264,12 @@ void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_Time, "called");
IPC::RequestParser rp{ctx};
- auto unknown_u8 = rp.PopRaw<u8>();
-
- ClockSnapshot clock_snapshot{};
+ const auto initial_type = rp.PopRaw<u8>();
const s64 time_since_epoch{std::chrono::duration_cast<std::chrono::seconds>(
std::chrono::system_clock::now().time_since_epoch())
.count()};
- CalendarTime calendar_time{};
+
const std::time_t time(time_since_epoch);
const std::tm* tm = std::localtime(&time);
if (tm == nullptr) {
@@ -280,16 +278,19 @@ void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) {
rb.Push(ResultCode(-1)); // TODO(ogniK): Find appropriate error code
return;
}
- SteadyClockTimePoint steady_clock_time_point{CoreTiming::cyclesToMs(CoreTiming::GetTicks()) /
- 1000};
- LocationName location_name{"UTC"};
+ const SteadyClockTimePoint steady_clock_time_point{
+ CoreTiming::cyclesToMs(CoreTiming::GetTicks()) / 1000, {}};
+
+ CalendarTime calendar_time{};
calendar_time.year = tm->tm_year + 1900;
calendar_time.month = tm->tm_mon + 1;
calendar_time.day = tm->tm_mday;
calendar_time.hour = tm->tm_hour;
calendar_time.minute = tm->tm_min;
calendar_time.second = tm->tm_sec;
+
+ ClockSnapshot clock_snapshot{};
clock_snapshot.system_posix_time = time_since_epoch;
clock_snapshot.network_posix_time = time_since_epoch;
clock_snapshot.system_calendar_time = calendar_time;
@@ -302,9 +303,10 @@ void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) {
clock_snapshot.network_calendar_info = additional_info;
clock_snapshot.steady_clock_timepoint = steady_clock_time_point;
- clock_snapshot.location_name = location_name;
+ clock_snapshot.location_name = LocationName{"UTC"};
clock_snapshot.clock_auto_adjustment_enabled = 1;
- clock_snapshot.ipc_u8 = unknown_u8;
+ clock_snapshot.type = initial_type;
+
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
ctx.WriteBuffer(&clock_snapshot, sizeof(ClockSnapshot));
diff --git a/src/core/hle/service/time/time.h b/src/core/hle/service/time/time.h
index ea43fbea7..f11affe95 100644
--- a/src/core/hle/service/time/time.h
+++ b/src/core/hle/service/time/time.h
@@ -22,7 +22,6 @@ struct CalendarTime {
u8 hour;
u8 minute;
u8 second;
- INSERT_PADDING_BYTES(1);
};
static_assert(sizeof(CalendarTime) == 0x8, "CalendarTime structure has incorrect size");
@@ -30,7 +29,7 @@ struct CalendarAdditionalInfo {
u32_le day_of_week;
u32_le day_of_year;
std::array<u8, 8> name;
- INSERT_PADDING_BYTES(1);
+ u8 is_dst;
s32_le utc_offset;
};
static_assert(sizeof(CalendarAdditionalInfo) == 0x18,
@@ -42,8 +41,10 @@ struct TimeZoneRule {
};
struct SteadyClockTimePoint {
+ using SourceID = std::array<u8, 16>;
+
u64_le value;
- INSERT_PADDING_WORDS(4);
+ SourceID source_id;
};
static_assert(sizeof(SteadyClockTimePoint) == 0x18, "SteadyClockTimePoint is incorrect size");
@@ -66,8 +67,9 @@ struct ClockSnapshot {
SteadyClockTimePoint steady_clock_timepoint;
LocationName location_name;
u8 clock_auto_adjustment_enabled;
- u8 ipc_u8;
- INSERT_PADDING_BYTES(2);
+ u8 type;
+ u8 version;
+ INSERT_PADDING_BYTES(1);
};
static_assert(sizeof(ClockSnapshot) == 0xd0, "ClockSnapshot is an invalid size");
diff --git a/src/video_core/morton.cpp b/src/video_core/morton.cpp
index 47e76d8fe..b68f4fb13 100644
--- a/src/video_core/morton.cpp
+++ b/src/video_core/morton.cpp
@@ -66,8 +66,6 @@ static constexpr ConversionArray morton_to_linear_fns = {
MortonCopy<true, PixelFormat::BC6H_UF16>,
MortonCopy<true, PixelFormat::BC6H_SF16>,
MortonCopy<true, PixelFormat::ASTC_2D_4X4>,
- MortonCopy<true, PixelFormat::G8R8U>,
- MortonCopy<true, PixelFormat::G8R8S>,
MortonCopy<true, PixelFormat::BGRA8>,
MortonCopy<true, PixelFormat::RGBA32F>,
MortonCopy<true, PixelFormat::RG32F>,
@@ -138,8 +136,6 @@ static constexpr ConversionArray linear_to_morton_fns = {
MortonCopy<false, PixelFormat::BC6H_SF16>,
// TODO(Subv): Swizzling ASTC formats are not supported
nullptr,
- MortonCopy<false, PixelFormat::G8R8U>,
- MortonCopy<false, PixelFormat::G8R8S>,
MortonCopy<false, PixelFormat::BGRA8>,
MortonCopy<false, PixelFormat::RGBA32F>,
MortonCopy<false, PixelFormat::RG32F>,
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index 7ea07631a..75b4fe88d 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -288,8 +288,6 @@ static constexpr std::array<FormatTuple, VideoCore::Surface::MaxPixelFormat> tex
{GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT, GL_RGB, GL_UNSIGNED_INT_8_8_8_8, ComponentType::Float,
true}, // BC6H_SF16
{GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_4X4
- {GL_RG8, GL_RG, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // G8R8U
- {GL_RG8, GL_RG, GL_BYTE, ComponentType::SNorm, false}, // G8R8S
{GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // BGRA8
{GL_RGBA32F, GL_RGBA, GL_FLOAT, ComponentType::Float, false}, // RGBA32F
{GL_RG32F, GL_RG, GL_FLOAT, ComponentType::Float, false}, // RG32F
@@ -620,18 +618,6 @@ static void ConvertS8Z24ToZ24S8(std::vector<u8>& data, u32 width, u32 height, bo
}
}
-static void ConvertG8R8ToR8G8(std::vector<u8>& data, u32 width, u32 height) {
- constexpr auto bpp{GetBytesPerPixel(PixelFormat::G8R8U)};
- for (std::size_t y = 0; y < height; ++y) {
- for (std::size_t x = 0; x < width; ++x) {
- const std::size_t offset{bpp * (y * width + x)};
- const u8 temp{data[offset]};
- data[offset] = data[offset + 1];
- data[offset + 1] = temp;
- }
- }
-}
-
/**
* Helper function to perform software conversion (as needed) when loading a buffer from Switch
* memory. This is for Maxwell pixel formats that cannot be represented as-is in OpenGL or with
@@ -664,12 +650,6 @@ static void ConvertFormatAsNeeded_LoadGLBuffer(std::vector<u8>& data, PixelForma
// Convert the S8Z24 depth format to Z24S8, as OpenGL does not support S8Z24.
ConvertS8Z24ToZ24S8(data, width, height, false);
break;
-
- case PixelFormat::G8R8U:
- case PixelFormat::G8R8S:
- // Convert the G8R8 color format to R8G8, as OpenGL does not support G8R8.
- ConvertG8R8ToR8G8(data, width, height);
- break;
}
}
@@ -681,8 +661,6 @@ static void ConvertFormatAsNeeded_LoadGLBuffer(std::vector<u8>& data, PixelForma
static void ConvertFormatAsNeeded_FlushGLBuffer(std::vector<u8>& data, PixelFormat pixel_format,
u32 width, u32 height) {
switch (pixel_format) {
- case PixelFormat::G8R8U:
- case PixelFormat::G8R8S:
case PixelFormat::ASTC_2D_4X4:
case PixelFormat::ASTC_2D_8X8:
case PixelFormat::ASTC_2D_4X4_SRGB:
diff --git a/src/video_core/surface.cpp b/src/video_core/surface.cpp
index a97b1562b..1a344229f 100644
--- a/src/video_core/surface.cpp
+++ b/src/video_core/surface.cpp
@@ -196,11 +196,14 @@ PixelFormat PixelFormatFromTextureFormat(Tegra::Texture::TextureFormat format,
LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", static_cast<u32>(component_type));
UNREACHABLE();
case Tegra::Texture::TextureFormat::G8R8:
+ // TextureFormat::G8R8 is actually ordered red then green, as such we can use
+ // PixelFormat::RG8U and PixelFormat::RG8S. This was tested with The Legend of Zelda: Breath
+ // of the Wild, which uses this format to render the hearts on the UI.
switch (component_type) {
case Tegra::Texture::ComponentType::UNORM:
- return PixelFormat::G8R8U;
+ return PixelFormat::RG8U;
case Tegra::Texture::ComponentType::SNORM:
- return PixelFormat::G8R8S;
+ return PixelFormat::RG8S;
}
LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", static_cast<u32>(component_type));
UNREACHABLE();
diff --git a/src/video_core/surface.h b/src/video_core/surface.h
index e23cfecbc..c2259c3c2 100644
--- a/src/video_core/surface.h
+++ b/src/video_core/surface.h
@@ -38,57 +38,55 @@ enum class PixelFormat {
BC6H_UF16 = 20,
BC6H_SF16 = 21,
ASTC_2D_4X4 = 22,
- G8R8U = 23,
- G8R8S = 24,
- BGRA8 = 25,
- RGBA32F = 26,
- RG32F = 27,
- R32F = 28,
- R16F = 29,
- R16U = 30,
- R16S = 31,
- R16UI = 32,
- R16I = 33,
- RG16 = 34,
- RG16F = 35,
- RG16UI = 36,
- RG16I = 37,
- RG16S = 38,
- RGB32F = 39,
- RGBA8_SRGB = 40,
- RG8U = 41,
- RG8S = 42,
- RG32UI = 43,
- R32UI = 44,
- ASTC_2D_8X8 = 45,
- ASTC_2D_8X5 = 46,
- ASTC_2D_5X4 = 47,
- BGRA8_SRGB = 48,
- DXT1_SRGB = 49,
- DXT23_SRGB = 50,
- DXT45_SRGB = 51,
- BC7U_SRGB = 52,
- ASTC_2D_4X4_SRGB = 53,
- ASTC_2D_8X8_SRGB = 54,
- ASTC_2D_8X5_SRGB = 55,
- ASTC_2D_5X4_SRGB = 56,
- ASTC_2D_5X5 = 57,
- ASTC_2D_5X5_SRGB = 58,
- ASTC_2D_10X8 = 59,
- ASTC_2D_10X8_SRGB = 60,
+ BGRA8 = 23,
+ RGBA32F = 24,
+ RG32F = 25,
+ R32F = 26,
+ R16F = 27,
+ R16U = 28,
+ R16S = 29,
+ R16UI = 30,
+ R16I = 31,
+ RG16 = 32,
+ RG16F = 33,
+ RG16UI = 34,
+ RG16I = 35,
+ RG16S = 36,
+ RGB32F = 37,
+ RGBA8_SRGB = 38,
+ RG8U = 39,
+ RG8S = 40,
+ RG32UI = 41,
+ R32UI = 42,
+ ASTC_2D_8X8 = 43,
+ ASTC_2D_8X5 = 44,
+ ASTC_2D_5X4 = 45,
+ BGRA8_SRGB = 46,
+ DXT1_SRGB = 47,
+ DXT23_SRGB = 48,
+ DXT45_SRGB = 49,
+ BC7U_SRGB = 50,
+ ASTC_2D_4X4_SRGB = 51,
+ ASTC_2D_8X8_SRGB = 52,
+ ASTC_2D_8X5_SRGB = 53,
+ ASTC_2D_5X4_SRGB = 54,
+ ASTC_2D_5X5 = 55,
+ ASTC_2D_5X5_SRGB = 56,
+ ASTC_2D_10X8 = 57,
+ ASTC_2D_10X8_SRGB = 58,
MaxColorFormat,
// Depth formats
- Z32F = 61,
- Z16 = 62,
+ Z32F = 59,
+ Z16 = 60,
MaxDepthFormat,
// DepthStencil formats
- Z24S8 = 63,
- S8Z24 = 64,
- Z32FS8 = 65,
+ Z24S8 = 61,
+ S8Z24 = 62,
+ Z32FS8 = 63,
MaxDepthStencilFormat,
@@ -149,8 +147,6 @@ constexpr std::array<u32, MaxPixelFormat> compression_factor_table = {{
4, // BC6H_UF16
4, // BC6H_SF16
4, // ASTC_2D_4X4
- 1, // G8R8U
- 1, // G8R8S
1, // BGRA8
1, // RGBA32F
1, // RG32F
@@ -232,8 +228,6 @@ constexpr std::array<u32, MaxPixelFormat> block_width_table = {{
4, // BC6H_UF16
4, // BC6H_SF16
4, // ASTC_2D_4X4
- 1, // G8R8U
- 1, // G8R8S
1, // BGRA8
1, // RGBA32F
1, // RG32F
@@ -309,8 +303,6 @@ constexpr std::array<u32, MaxPixelFormat> block_height_table = {{
4, // BC6H_UF16
4, // BC6H_SF16
4, // ASTC_2D_4X4
- 1, // G8R8U
- 1, // G8R8S
1, // BGRA8
1, // RGBA32F
1, // RG32F
@@ -386,8 +378,6 @@ constexpr std::array<u32, MaxPixelFormat> bpp_table = {{
128, // BC6H_UF16
128, // BC6H_SF16
128, // ASTC_2D_4X4
- 16, // G8R8U
- 16, // G8R8S
32, // BGRA8
128, // RGBA32F
64, // RG32F