From 1c972ef3b93252a157ec15d0878a2be3e4b46a0e Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Wed, 10 Dec 2014 21:51:00 +0100 Subject: Add support for a ridiculous number of texture formats. --- src/citra_qt/debugger/graphics_cmdlists.cpp | 9 +++- src/video_core/debug_utils/debug_utils.cpp | 65 ++++++++++++++++++++++++++++- src/video_core/pica.h | 22 +++++++--- 3 files changed, 88 insertions(+), 8 deletions(-) diff --git a/src/citra_qt/debugger/graphics_cmdlists.cpp b/src/citra_qt/debugger/graphics_cmdlists.cpp index bf35f035..95187e54 100644 --- a/src/citra_qt/debugger/graphics_cmdlists.cpp +++ b/src/citra_qt/debugger/graphics_cmdlists.cpp @@ -69,6 +69,13 @@ TextureInfoDockWidget::TextureInfoDockWidget(const Pica::DebugUtils::TextureInfo format_choice->addItem(tr("RGBA5551")); format_choice->addItem(tr("RGB565")); format_choice->addItem(tr("RGBA4")); + format_choice->addItem(tr("IA8")); + format_choice->addItem(tr("UNK6")); + format_choice->addItem(tr("I8")); + format_choice->addItem(tr("A8")); + format_choice->addItem(tr("IA4")); + format_choice->addItem(tr("UNK10")); + format_choice->addItem(tr("A4")); format_choice->setCurrentIndex(static_cast(info.format)); connect(format_choice, SIGNAL(currentIndexChanged(int)), this, SLOT(OnFormatChanged(int))); @@ -265,7 +272,7 @@ void GPUCommandListWidget::SetCommandInfo(const QModelIndex& index) { auto format = Pica::registers.GetTextures()[index].format; auto info = Pica::DebugUtils::TextureInfo::FromPicaRegister(config, format); - u8* src = Memory::GetPointer(config.GetPhysicalAddress()); + u8* src = Memory::GetPointer(Pica::PAddrToVAddr(config.GetPhysicalAddress())); new_info_widget = new TextureInfoWidget(src, info); } else { new_info_widget = new QWidget; diff --git a/src/video_core/debug_utils/debug_utils.cpp b/src/video_core/debug_utils/debug_utils.cpp index 08ecd4cc..1a7b851d 100644 --- a/src/video_core/debug_utils/debug_utils.cpp +++ b/src/video_core/debug_utils/debug_utils.cpp @@ -418,6 +418,15 @@ const Math::Vec4 LookupTexture(const u8* source, int x, int y, const Texture return Math::MakeVec((r << 3) | (r >> 2), (g << 3) | (g >> 2), (b << 3) | (b >> 2), disable_alpha ? 255 : (a * 255)); } + case Regs::TextureFormat::RGB565: + { + const u16 source_ptr = *(const u16*)(source + coarse_x * block_height * 2 + coarse_y * info.stride + texel_index_within_tile * 2); + u8 r = (source_ptr >> 11) & 0x1F; + u8 g = ((source_ptr) >> 5) & 0x3F; + u8 b = (source_ptr) & 0x1F; + return Math::MakeVec((r << 3) | (r >> 2), (g << 2) | (g >> 4), (b << 3) | (b >> 2), 255); + } + case Regs::TextureFormat::RGBA4: { const u8* source_ptr = source + coarse_x * block_height * 2 + coarse_y * info.stride + texel_index_within_tile * 2; @@ -432,6 +441,26 @@ const Math::Vec4 LookupTexture(const u8* source, int x, int y, const Texture return { r, g, b, disable_alpha ? 255 : a }; } + case Regs::TextureFormat::IA8: + { + const u8* source_ptr = source + coarse_x * block_height * 2 + coarse_y * info.stride + texel_index_within_tile * 2; + + // TODO: Better control this... + if (disable_alpha) { + return { *source_ptr, *(source_ptr+1), 0, 255 }; + } else { + return { *source_ptr, *source_ptr, *source_ptr, *(source_ptr+1)}; + } + } + + case Regs::TextureFormat::I8: + { + const u8* source_ptr = source + coarse_x * block_height + coarse_y * info.stride + texel_index_within_tile; + + // TODO: Better control this... + return { *source_ptr, *source_ptr, *source_ptr, 255 }; + } + case Regs::TextureFormat::A8: { const u8* source_ptr = source + coarse_x * block_height + coarse_y * info.stride + texel_index_within_tile; @@ -444,6 +473,40 @@ const Math::Vec4 LookupTexture(const u8* source, int x, int y, const Texture } } + case Regs::TextureFormat::IA4: + { + const u8* source_ptr = source + coarse_x * block_height / 2 + coarse_y * info.stride + texel_index_within_tile / 2; + + // TODO: Order? + u8 i = (*source_ptr)&0xF; + u8 a = ((*source_ptr) & 0xF0) >> 4; + a |= a << 4; + i |= i << 4; + + // TODO: Better control this... + if (disable_alpha) { + return { i, a, 0, 255 }; + } else { + return { i, i, i, a }; + } + } + + case Regs::TextureFormat::A4: + { + const u8* source_ptr = source + coarse_x * block_height / 2 + coarse_y * info.stride + texel_index_within_tile / 2; + + // TODO: Order? + u8 a = (coarse_x % 2) ? ((*source_ptr)&0xF) : (((*source_ptr) & 0xF0) >> 4); + a |= a << 4; + + // TODO: Better control this... + if (disable_alpha) { + return { *source_ptr, *source_ptr, *source_ptr, 255 }; + } else { + return { 0, 0, 0, *source_ptr }; + } + } + default: LOG_ERROR(HW_GPU, "Unknown texture format: %x", (u32)info.format); _dbg_assert_(HW_GPU, 0); @@ -459,7 +522,7 @@ TextureInfo TextureInfo::FromPicaRegister(const Regs::TextureConfig& config, info.width = config.width; info.height = config.height; info.format = format; - info.stride = Pica::Regs::BytesPerPixel(info.format) * info.width; + info.stride = Pica::Regs::NibblesPerPixel(info.format) * info.width / 2; return info; } diff --git a/src/video_core/pica.h b/src/video_core/pica.h index 7d82d733..58361432 100644 --- a/src/video_core/pica.h +++ b/src/video_core/pica.h @@ -142,29 +142,39 @@ struct Regs { RGBA5551 = 2, RGB565 = 3, RGBA4 = 4, + IA8 = 5, + I8 = 7, A8 = 8, + IA4 = 9, + A4 = 11, // TODO: Support for the other formats is not implemented, yet. // Seems like they are luminance formats and compressed textures. }; - static unsigned BytesPerPixel(TextureFormat format) { + static unsigned NibblesPerPixel(TextureFormat format) { switch (format) { case TextureFormat::RGBA8: - return 4; + return 8; case TextureFormat::RGB8: - return 3; + return 6; case TextureFormat::RGBA5551: case TextureFormat::RGB565: case TextureFormat::RGBA4: - return 2; + case TextureFormat::IA8: + return 4; - default: - // placeholder for yet unknown formats + case TextureFormat::A4: return 1; + + case TextureFormat::I8: + case TextureFormat::A8: + case TextureFormat::IA4: + default: // placeholder for yet unknown formats + return 2; } } -- cgit v1.2.3