From c81f1a9ebc9a5f9df9add64e282d9a0c0da96e79 Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Sat, 6 Dec 2014 21:20:56 +0100 Subject: Pica/DebugUtils: Add support for RGBA8, RGBA5551, RGBA4 and A8 texture formats. --- src/video_core/debug_utils/debug_utils.cpp | 49 ++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 3 deletions(-) (limited to 'src/video_core/debug_utils') diff --git a/src/video_core/debug_utils/debug_utils.cpp b/src/video_core/debug_utils/debug_utils.cpp index 1a20f19ec..89bf08b99 100644 --- a/src/video_core/debug_utils/debug_utils.cpp +++ b/src/video_core/debug_utils/debug_utils.cpp @@ -357,7 +357,6 @@ std::unique_ptr FinishPicaTracing() } const Math::Vec4 LookupTexture(const u8* source, int x, int y, const TextureInfo& info) { - _dbg_assert_(Debug_GPU, info.format == Pica::Regs::TextureFormat::RGB8); // Cf. rasterizer code for an explanation of this algorithm. int texel_index_within_tile = 0; @@ -376,8 +375,52 @@ const Math::Vec4 LookupTexture(const u8* source, int x, int y, const Texture int coarse_x = (x / block_width) * block_width; int coarse_y = (y / block_height) * block_height; - const u8* source_ptr = source + coarse_x * block_height * 3 + coarse_y * info.stride + texel_index_within_tile * 3; - return { source_ptr[2], source_ptr[1], source_ptr[0], 255 }; + switch (info.format) { + case Regs::TextureFormat::RGBA8: + { + const u8* source_ptr = source + coarse_x * block_height * 4 + coarse_y * info.stride + texel_index_within_tile * 4; + return { source_ptr[3], source_ptr[2], source_ptr[1], 255 }; + } + + case Regs::TextureFormat::RGB8: + { + const u8* source_ptr = source + coarse_x * block_height * 3 + coarse_y * info.stride + texel_index_within_tile * 3; + return { source_ptr[2], source_ptr[1], source_ptr[0], 255 }; + } + + case Regs::TextureFormat::RGBA5551: + { + 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) >> 6) & 0x1F; + u8 b = (source_ptr >> 1) & 0x1F; + u8 a = 1; + return Math::MakeVec((r << 3) | (r >> 2), (g << 3) | (g >> 2), (b << 3) | (b >> 2), a * 255); + } + + case Regs::TextureFormat::RGBA4: + { + const u8* source_ptr = source + coarse_x * block_height * 2 + coarse_y * info.stride + texel_index_within_tile * 2; + u8 r = source_ptr[1] >> 4; + u8 g = source_ptr[1] & 0xFF; + u8 b = source_ptr[0] >> 4; + r = (r << 4) | r; + g = (g << 4) | g; + b = (b << 4) | b; + return { r, g, b, 255 }; + } + + case Regs::TextureFormat::A8: + { + const u8* source_ptr = source + coarse_x * block_height + coarse_y * info.stride + texel_index_within_tile; + return { *source_ptr, *source_ptr, *source_ptr, 255 }; + } + + default: + LOG_ERROR(HW_GPU, "Unknown texture format: %x", (u32)info.format); + _dbg_assert_(HW_GPU, 0); + return {}; + } } TextureInfo TextureInfo::FromPicaRegister(const Regs::TextureConfig& config, -- cgit v1.2.3 From 3df88d59b0ba43f1c3360cfdaaccd461cacff72c Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Sat, 6 Dec 2014 21:52:21 +0100 Subject: Pica: Merge texture lookup logic for DebugUtils and Rasterizer. This effectively adds support for a lot texture formats in the rasterizer. --- src/citra_qt/debugger/graphics_cmdlists.cpp | 2 +- src/video_core/debug_utils/debug_utils.cpp | 44 +++++++++++++++++++++----- src/video_core/debug_utils/debug_utils.h | 3 +- src/video_core/rasterizer.cpp | 49 ++--------------------------- 4 files changed, 42 insertions(+), 56 deletions(-) (limited to 'src/video_core/debug_utils') diff --git a/src/citra_qt/debugger/graphics_cmdlists.cpp b/src/citra_qt/debugger/graphics_cmdlists.cpp index bdd676470..01ff31d44 100644 --- a/src/citra_qt/debugger/graphics_cmdlists.cpp +++ b/src/citra_qt/debugger/graphics_cmdlists.cpp @@ -24,7 +24,7 @@ QImage LoadTexture(u8* src, const Pica::DebugUtils::TextureInfo& info) { QImage decoded_image(info.width, info.height, QImage::Format_ARGB32); for (int y = 0; y < info.height; ++y) { for (int x = 0; x < info.width; ++x) { - Math::Vec4 color = Pica::DebugUtils::LookupTexture(src, x, y, info); + Math::Vec4 color = Pica::DebugUtils::LookupTexture(src, x, y, info, true); decoded_image.setPixel(x, y, qRgba(color.r(), color.g(), color.b(), color.a())); } } diff --git a/src/video_core/debug_utils/debug_utils.cpp b/src/video_core/debug_utils/debug_utils.cpp index 89bf08b99..6c26138da 100644 --- a/src/video_core/debug_utils/debug_utils.cpp +++ b/src/video_core/debug_utils/debug_utils.cpp @@ -356,9 +356,29 @@ std::unique_ptr FinishPicaTracing() return std::move(ret); } -const Math::Vec4 LookupTexture(const u8* source, int x, int y, const TextureInfo& info) { - - // Cf. rasterizer code for an explanation of this algorithm. +const Math::Vec4 LookupTexture(const u8* source, int x, int y, const TextureInfo& info, bool disable_alpha) { + + // Images are split into 8x8 tiles. Each tile is composed of four 4x4 subtiles each + // of which is composed of four 2x2 subtiles each of which is composed of four texels. + // Each structure is embedded into the next-bigger one in a diagonal pattern, e.g. + // texels are laid out in a 2x2 subtile like this: + // 2 3 + // 0 1 + // + // The full 8x8 tile has the texels arranged like this: + // + // 42 43 46 47 58 59 62 63 + // 40 41 44 45 56 57 60 61 + // 34 35 38 39 50 51 54 55 + // 32 33 36 37 48 49 52 53 + // 10 11 14 15 26 27 30 31 + // 08 09 12 13 24 25 28 29 + // 02 03 06 07 18 19 22 23 + // 00 01 04 05 16 17 20 21 + + // TODO(neobrain): Not sure if this swizzling pattern is used for all textures. + // To be flexible in case different but similar patterns are used, we keep this + // somewhat inefficient code around for now. int texel_index_within_tile = 0; for (int block_size_index = 0; block_size_index < 3; ++block_size_index) { int sub_tile_width = 1 << block_size_index; @@ -379,7 +399,7 @@ const Math::Vec4 LookupTexture(const u8* source, int x, int y, const Texture case Regs::TextureFormat::RGBA8: { const u8* source_ptr = source + coarse_x * block_height * 4 + coarse_y * info.stride + texel_index_within_tile * 4; - return { source_ptr[3], source_ptr[2], source_ptr[1], 255 }; + return { source_ptr[3], source_ptr[2], source_ptr[1], disable_alpha ? 255 : source_ptr[0] }; } case Regs::TextureFormat::RGB8: @@ -394,8 +414,8 @@ const Math::Vec4 LookupTexture(const u8* source, int x, int y, const Texture u8 r = (source_ptr >> 11) & 0x1F; u8 g = ((source_ptr) >> 6) & 0x1F; u8 b = (source_ptr >> 1) & 0x1F; - u8 a = 1; - return Math::MakeVec((r << 3) | (r >> 2), (g << 3) | (g >> 2), (b << 3) | (b >> 2), a * 255); + u8 a = source_ptr & 1; + return Math::MakeVec((r << 3) | (r >> 2), (g << 3) | (g >> 2), (b << 3) | (b >> 2), disable_alpha ? 255 : (a * 255)); } case Regs::TextureFormat::RGBA4: @@ -404,16 +424,24 @@ const Math::Vec4 LookupTexture(const u8* source, int x, int y, const Texture u8 r = source_ptr[1] >> 4; u8 g = source_ptr[1] & 0xFF; u8 b = source_ptr[0] >> 4; + u8 a = source_ptr[0] & 0xFF; r = (r << 4) | r; g = (g << 4) | g; b = (b << 4) | b; - return { r, g, b, 255 }; + a = (a << 4) | a; + return { r, g, b, disable_alpha ? 255 : a }; } case Regs::TextureFormat::A8: { const u8* source_ptr = source + coarse_x * block_height + coarse_y * info.stride + texel_index_within_tile; - return { *source_ptr, *source_ptr, *source_ptr, 255 }; + + // TODO: Better control this... + if (disable_alpha) { + return { *source_ptr, *source_ptr, *source_ptr, 255 }; + } else { + return { 0, 0, 0, *source_ptr }; + } } default: diff --git a/src/video_core/debug_utils/debug_utils.h b/src/video_core/debug_utils/debug_utils.h index 51f14f12f..f950356f3 100644 --- a/src/video_core/debug_utils/debug_utils.h +++ b/src/video_core/debug_utils/debug_utils.h @@ -202,7 +202,8 @@ struct TextureInfo { const Pica::Regs::TextureFormat& format); }; -const Math::Vec4 LookupTexture(const u8* source, int x, int y, const TextureInfo& info); +const Math::Vec4 LookupTexture(const u8* source, int x, int y, const TextureInfo& info, + bool disable_alpha = false); void DumpTexture(const Pica::Regs::TextureConfig& texture_config, u8* data); void DumpTevStageConfig(const std::array& stages); diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp index e12f68a7f..aa2bc93ec 100644 --- a/src/video_core/rasterizer.cpp +++ b/src/video_core/rasterizer.cpp @@ -183,27 +183,6 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0, _dbg_assert_(HW_GPU, 0 != texture.config.address); - // Images are split into 8x8 tiles. Each tile is composed of four 4x4 subtiles each - // of which is composed of four 2x2 subtiles each of which is composed of four texels. - // Each structure is embedded into the next-bigger one in a diagonal pattern, e.g. - // texels are laid out in a 2x2 subtile like this: - // 2 3 - // 0 1 - // - // The full 8x8 tile has the texels arranged like this: - // - // 42 43 46 47 58 59 62 63 - // 40 41 44 45 56 57 60 61 - // 34 35 38 39 50 51 54 55 - // 32 33 36 37 48 49 52 53 - // 10 11 14 15 26 27 30 31 - // 08 09 12 13 24 25 28 29 - // 02 03 06 07 18 19 22 23 - // 00 01 04 05 16 17 20 21 - - // TODO(neobrain): Not sure if this swizzling pattern is used for all textures. - // To be flexible in case different but similar patterns are used, we keep this - // somewhat inefficient code around for now. int s = (int)(uv[i].u() * float24::FromFloat32(static_cast(texture.config.width))).ToFloat32(); int t = (int)(uv[i].v() * float24::FromFloat32(static_cast(texture.config.height))).ToFloat32(); auto GetWrappedTexCoord = [](Regs::TextureConfig::WrapMode mode, int val, unsigned size) { @@ -225,32 +204,10 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0, s = GetWrappedTexCoord(registers.texture0.wrap_s, s, registers.texture0.width); t = GetWrappedTexCoord(registers.texture0.wrap_t, t, registers.texture0.height); - int texel_index_within_tile = 0; - for (int block_size_index = 0; block_size_index < 3; ++block_size_index) { - int sub_tile_width = 1 << block_size_index; - int sub_tile_height = 1 << block_size_index; - - int sub_tile_index = (s & sub_tile_width) << block_size_index; - sub_tile_index += 2 * ((t & sub_tile_height) << block_size_index); - texel_index_within_tile += sub_tile_index; - } - - const int block_width = 8; - const int block_height = 8; - - int coarse_s = (s / block_width) * block_width; - int coarse_t = (t / block_height) * block_height; - - // TODO: This is currently hardcoded for RGB8 - u32* texture_data = (u32*)Memory::GetPointer(texture.config.GetPhysicalAddress()); - - const int row_stride = texture.config.width * 3; - u8* source_ptr = (u8*)texture_data + coarse_s * block_height * 3 + coarse_t * row_stride + texel_index_within_tile * 3; - texture_color[i].r() = source_ptr[2]; - texture_color[i].g() = source_ptr[1]; - texture_color[i].b() = source_ptr[0]; - texture_color[i].a() = 0xFF; + u8* texture_data = Memory::GetPointer(texture.config.GetPhysicalAddress()); + auto info = DebugUtils::TextureInfo::FromPicaRegister(texture.config, texture.format); + texture_color[i] = DebugUtils::LookupTexture(texture_data, s, t, info); DebugUtils::DumpTexture(texture.config, (u8*)texture_data); } -- cgit v1.2.3 From 7e210e0229b9caef77c80fea7c056c3913e68129 Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Fri, 24 Oct 2014 00:58:04 +0200 Subject: Pica: Further improve Tev emulation. --- src/video_core/debug_utils/debug_utils.cpp | 10 ++++-- src/video_core/pica.h | 1 + src/video_core/rasterizer.cpp | 52 ++++++++++++++++++++++++------ 3 files changed, 51 insertions(+), 12 deletions(-) (limited to 'src/video_core/debug_utils') diff --git a/src/video_core/debug_utils/debug_utils.cpp b/src/video_core/debug_utils/debug_utils.cpp index 6c26138da..3cc22f436 100644 --- a/src/video_core/debug_utils/debug_utils.cpp +++ b/src/video_core/debug_utils/debug_utils.cpp @@ -573,20 +573,26 @@ void DumpTevStageConfig(const std::array& stages) const std::map source_map = { { Source::PrimaryColor, "PrimaryColor" }, { Source::Texture0, "Texture0" }, + { Source::Texture1, "Texture1" }, + { Source::Texture2, "Texture2" }, { Source::Constant, "Constant" }, { Source::Previous, "Previous" }, }; const std::map color_modifier_map = { - { ColorModifier::SourceColor, { "%source.rgb" } } + { ColorModifier::SourceColor, { "%source.rgb" } }, + { ColorModifier::SourceAlpha, { "%source.aaa" } }, }; const std::map alpha_modifier_map = { - { AlphaModifier::SourceAlpha, "%source.a" } + { AlphaModifier::SourceAlpha, "%source.a" }, + { AlphaModifier::OneMinusSourceAlpha, "(255 - %source.a)" }, }; std::map combiner_map = { { Operation::Replace, "%source1" }, { Operation::Modulate, "(%source1 * %source2) / 255" }, + { Operation::Add, "(%source1 + %source2)" }, + { Operation::Lerp, "lerp(%source1, %source2, %source3)" }, }; auto ReplacePattern = diff --git a/src/video_core/pica.h b/src/video_core/pica.h index ec20114fe..5712439e1 100644 --- a/src/video_core/pica.h +++ b/src/video_core/pica.h @@ -8,6 +8,7 @@ #include #include #include +#include #include "common/bit_field.h" #include "common/common_types.h" diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp index aa2bc93ec..25efd49c8 100644 --- a/src/video_core/rasterizer.cpp +++ b/src/video_core/rasterizer.cpp @@ -225,28 +225,29 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0, using AlphaModifier = Regs::TevStageConfig::AlphaModifier; using Operation = Regs::TevStageConfig::Operation; - auto GetColorSource = [&](Source source) -> Math::Vec3 { + auto GetColorSource = [&](Source source) -> Math::Vec4 { switch (source) { case Source::PrimaryColor: - return primary_color.rgb(); + return primary_color; case Source::Texture0: - return texture_color[0].rgb(); + return texture_color[0]; case Source::Texture1: - return texture_color[1].rgb(); + return texture_color[1]; case Source::Texture2: - return texture_color[2].rgb(); + return texture_color[2]; case Source::Constant: - return {tev_stage.const_r, tev_stage.const_g, tev_stage.const_b}; + return {tev_stage.const_r, tev_stage.const_g, tev_stage.const_b, tev_stage.const_a}; case Source::Previous: - return combiner_output.rgb(); + return combiner_output; default: LOG_ERROR(HW_GPU, "Unknown color combiner source %d\n", (int)source); + _dbg_assert_(HW_GPU, 0); return {}; } }; @@ -273,17 +274,23 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0, default: LOG_ERROR(HW_GPU, "Unknown alpha combiner source %d\n", (int)source); + _dbg_assert_(HW_GPU, 0); return 0; } }; - auto GetColorModifier = [](ColorModifier factor, const Math::Vec3& values) -> Math::Vec3 { + auto GetColorModifier = [](ColorModifier factor, const Math::Vec4& values) -> Math::Vec3 { switch (factor) { case ColorModifier::SourceColor: - return values; + return values.rgb(); + + case ColorModifier::SourceAlpha: + return { values.a(), values.a(), values.a() }; + default: LOG_ERROR(HW_GPU, "Unknown color factor %d\n", (int)factor); + _dbg_assert_(HW_GPU, 0); return {}; } }; @@ -292,8 +299,13 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0, switch (factor) { case AlphaModifier::SourceAlpha: return value; + + case AlphaModifier::OneMinusSourceAlpha: + return 255 - value; + default: - LOG_ERROR(HW_GPU, "Unknown color factor %d\n", (int)factor); + LOG_ERROR(HW_GPU, "Unknown alpha factor %d\n", (int)factor); + _dbg_assert_(HW_GPU, 0); return 0; } }; @@ -306,8 +318,21 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0, case Operation::Modulate: return ((input[0] * input[1]) / 255).Cast(); + case Operation::Add: + { + auto result = input[0] + input[1]; + result.r() = std::min(255, result.r()); + result.g() = std::min(255, result.g()); + result.b() = std::min(255, result.b()); + return result.Cast(); + } + + case Operation::Lerp: + return ((input[0] * input[2] + input[1] * (Math::MakeVec(255, 255, 255) - input[2]).Cast()) / 255).Cast(); + default: LOG_ERROR(HW_GPU, "Unknown color combiner operation %d\n", (int)op); + _dbg_assert_(HW_GPU, 0); return {}; } }; @@ -320,8 +345,15 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0, case Operation::Modulate: return input[0] * input[1] / 255; + case Operation::Add: + return std::min(255, input[0] + input[1]); + + case Operation::Lerp: + return (input[0] * input[2] + input[1] * (255 - input[2])) / 255; + default: LOG_ERROR(HW_GPU, "Unknown alpha combiner operation %d\n", (int)op); + _dbg_assert_(HW_GPU, 0); return 0; } }; -- cgit v1.2.3 From 40f123b7c0eaf1507d51f6b87192ec2f956e5d5e Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Mon, 15 Dec 2014 21:28:45 +0100 Subject: Pica: Unify ugly address translation hacks. --- src/citra_qt/debugger/graphics_cmdlists.cpp | 8 ++++---- src/citra_qt/debugger/graphics_framebuffer.cpp | 8 ++++---- src/video_core/command_processor.cpp | 4 ++-- src/video_core/debug_utils/debug_utils.cpp | 2 +- src/video_core/debug_utils/debug_utils.h | 2 +- src/video_core/pica.h | 25 +++++++++++++++++-------- src/video_core/rasterizer.cpp | 8 ++++---- 7 files changed, 33 insertions(+), 24 deletions(-) (limited to 'src/video_core/debug_utils') diff --git a/src/citra_qt/debugger/graphics_cmdlists.cpp b/src/citra_qt/debugger/graphics_cmdlists.cpp index 01ff31d44..bf35f035f 100644 --- a/src/citra_qt/debugger/graphics_cmdlists.cpp +++ b/src/citra_qt/debugger/graphics_cmdlists.cpp @@ -47,7 +47,7 @@ public: }; TextureInfoDockWidget::TextureInfoDockWidget(const Pica::DebugUtils::TextureInfo& info, QWidget* parent) - : QDockWidget(tr("Texture 0x%1").arg(info.address, 8, 16, QLatin1Char('0'))), + : QDockWidget(tr("Texture 0x%1").arg(info.physical_address, 8, 16, QLatin1Char('0'))), info(info) { QWidget* main_widget = new QWidget; @@ -60,7 +60,7 @@ TextureInfoDockWidget::TextureInfoDockWidget(const Pica::DebugUtils::TextureInfo phys_address_spinbox->SetBase(16); phys_address_spinbox->SetRange(0, 0xFFFFFFFF); phys_address_spinbox->SetPrefix("0x"); - phys_address_spinbox->SetValue(info.address); + phys_address_spinbox->SetValue(info.physical_address); connect(phys_address_spinbox, SIGNAL(ValueChanged(qint64)), this, SLOT(OnAddressChanged(qint64))); QComboBox* format_choice = new QComboBox; @@ -125,7 +125,7 @@ TextureInfoDockWidget::TextureInfoDockWidget(const Pica::DebugUtils::TextureInfo } void TextureInfoDockWidget::OnAddressChanged(qint64 value) { - info.address = value; + info.physical_address = value; emit UpdatePixmap(ReloadPixmap()); } @@ -150,7 +150,7 @@ void TextureInfoDockWidget::OnStrideChanged(int value) { } QPixmap TextureInfoDockWidget::ReloadPixmap() const { - u8* src = Memory::GetPointer(info.address); + u8* src = Memory::GetPointer(Pica::PAddrToVAddr(info.physical_address)); return QPixmap::fromImage(LoadTexture(src, info)); } diff --git a/src/citra_qt/debugger/graphics_framebuffer.cpp b/src/citra_qt/debugger/graphics_framebuffer.cpp index c055299a4..484be1db5 100644 --- a/src/citra_qt/debugger/graphics_framebuffer.cpp +++ b/src/citra_qt/debugger/graphics_framebuffer.cpp @@ -199,7 +199,7 @@ void GraphicsFramebufferWidget::OnUpdate() auto framebuffer = Pica::registers.framebuffer; using Framebuffer = decltype(framebuffer); - framebuffer_address = framebuffer.GetColorBufferAddress(); + framebuffer_address = framebuffer.GetColorBufferPhysicalAddress(); framebuffer_width = framebuffer.GetWidth(); framebuffer_height = framebuffer.GetHeight(); framebuffer_format = static_cast(framebuffer.color_format); @@ -224,7 +224,7 @@ void GraphicsFramebufferWidget::OnUpdate() case Format::RGBA8: { QImage decoded_image(framebuffer_width, framebuffer_height, QImage::Format_ARGB32); - u32* color_buffer = (u32*)Memory::GetPointer(framebuffer_address); + u32* color_buffer = (u32*)Memory::GetPointer(Pica::PAddrToVAddr(framebuffer_address)); for (unsigned y = 0; y < framebuffer_height; ++y) { for (unsigned x = 0; x < framebuffer_width; ++x) { u32 value = *(color_buffer + x + y * framebuffer_width); @@ -239,7 +239,7 @@ void GraphicsFramebufferWidget::OnUpdate() case Format::RGB8: { QImage decoded_image(framebuffer_width, framebuffer_height, QImage::Format_ARGB32); - u8* color_buffer = Memory::GetPointer(framebuffer_address); + u8* color_buffer = Memory::GetPointer(Pica::PAddrToVAddr(framebuffer_address)); for (unsigned y = 0; y < framebuffer_height; ++y) { for (unsigned x = 0; x < framebuffer_width; ++x) { u8* pixel_pointer = color_buffer + x * 3 + y * 3 * framebuffer_width; @@ -254,7 +254,7 @@ void GraphicsFramebufferWidget::OnUpdate() case Format::RGBA5551: { QImage decoded_image(framebuffer_width, framebuffer_height, QImage::Format_ARGB32); - u32* color_buffer = (u32*)Memory::GetPointer(framebuffer_address); + u32* color_buffer = (u32*)Memory::GetPointer(Pica::PAddrToVAddr(framebuffer_address)); for (unsigned y = 0; y < framebuffer_height; ++y) { for (unsigned x = 0; x < framebuffer_width; ++x) { u16 value = *(u16*)(((u8*)color_buffer) + x * 2 + y * framebuffer_width * 2); diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp index b74cd3261..3d06ac7e6 100644 --- a/src/video_core/command_processor.cpp +++ b/src/video_core/command_processor.cpp @@ -56,7 +56,7 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) { g_debug_context->OnEvent(DebugContext::Event::IncomingPrimitiveBatch, nullptr); const auto& attribute_config = registers.vertex_attributes; - const u8* const base_address = Memory::GetPointer(attribute_config.GetBaseAddress()); + const u8* const base_address = Memory::GetPointer(PAddrToVAddr(attribute_config.GetPhysicalBaseAddress())); // Information about internal vertex attributes const u8* vertex_attribute_sources[16]; @@ -116,7 +116,7 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) { input.attr[i][comp] = float24::FromFloat32(srcval); LOG_TRACE(HW_GPU, "Loaded component %x of attribute %x for vertex %x (index %x) from 0x%08x + 0x%08lx + 0x%04lx: %f", comp, i, vertex, index, - attribute_config.GetBaseAddress(), + PAddrToVAddr(attribute_config.GetPhysicalBaseAddress()), vertex_attribute_sources[i] - base_address, srcdata - vertex_attribute_sources[i], input.attr[i][comp].ToFloat32()); diff --git a/src/video_core/debug_utils/debug_utils.cpp b/src/video_core/debug_utils/debug_utils.cpp index 3cc22f436..08ecd4ccb 100644 --- a/src/video_core/debug_utils/debug_utils.cpp +++ b/src/video_core/debug_utils/debug_utils.cpp @@ -455,7 +455,7 @@ TextureInfo TextureInfo::FromPicaRegister(const Regs::TextureConfig& config, const Regs::TextureFormat& format) { TextureInfo info; - info.address = config.GetPhysicalAddress(); + info.physical_address = config.GetPhysicalAddress(); info.width = config.width; info.height = config.height; info.format = format; diff --git a/src/video_core/debug_utils/debug_utils.h b/src/video_core/debug_utils/debug_utils.h index f950356f3..2a764e121 100644 --- a/src/video_core/debug_utils/debug_utils.h +++ b/src/video_core/debug_utils/debug_utils.h @@ -192,7 +192,7 @@ void OnPicaRegWrite(u32 id, u32 value); std::unique_ptr FinishPicaTracing(); struct TextureInfo { - unsigned int address; + PAddr physical_address; int width; int height; int stride; diff --git a/src/video_core/pica.h b/src/video_core/pica.h index 5712439e1..7d82d733d 100644 --- a/src/video_core/pica.h +++ b/src/video_core/pica.h @@ -127,7 +127,7 @@ struct Regs { u32 address; u32 GetPhysicalAddress() const { - return DecodeAddressRegister(address) - Memory::FCRAM_PADDR + Memory::HEAP_LINEAR_VADDR; + return DecodeAddressRegister(address); } // texture1 and texture2 store the texture format directly after the address @@ -317,11 +317,11 @@ struct Regs { INSERT_PADDING_WORDS(0x1); - inline u32 GetColorBufferAddress() const { - return Memory::PhysicalToVirtualAddress(DecodeAddressRegister(color_buffer_address)); + inline u32 GetColorBufferPhysicalAddress() const { + return DecodeAddressRegister(color_buffer_address); } - inline u32 GetDepthBufferAddress() const { - return Memory::PhysicalToVirtualAddress(DecodeAddressRegister(depth_buffer_address)); + inline u32 GetDepthBufferPhysicalAddress() const { + return DecodeAddressRegister(depth_buffer_address); } inline u32 GetWidth() const { @@ -345,9 +345,8 @@ struct Regs { BitField<0, 29, u32> base_address; - inline u32 GetBaseAddress() const { - // TODO: Ugly, should fix PhysicalToVirtualAddress instead - return DecodeAddressRegister(base_address) - Memory::FCRAM_PADDR + Memory::HEAP_LINEAR_VADDR; + u32 GetPhysicalBaseAddress() const { + return DecodeAddressRegister(base_address); } // Descriptor for internal vertex attributes @@ -779,5 +778,15 @@ union CommandHeader { BitField<31, 1, u32> group_commands; }; +// TODO: Ugly, should fix PhysicalToVirtualAddress instead +inline static u32 PAddrToVAddr(u32 addr) { + if (addr >= Memory::VRAM_PADDR && addr < Memory::VRAM_PADDR + Memory::VRAM_SIZE) { + return addr - Memory::VRAM_PADDR + Memory::VRAM_VADDR; + } else if (addr >= Memory::FCRAM_PADDR && addr < Memory::FCRAM_PADDR + Memory::FCRAM_SIZE) { + return addr - Memory::FCRAM_PADDR + Memory::HEAP_LINEAR_VADDR; + } else { + return 0; + } +} } // namespace diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp index 25efd49c8..bd79e4413 100644 --- a/src/video_core/rasterizer.cpp +++ b/src/video_core/rasterizer.cpp @@ -18,7 +18,7 @@ namespace Pica { namespace Rasterizer { static void DrawPixel(int x, int y, const Math::Vec4& color) { - u32* color_buffer = (u32*)Memory::GetPointer(registers.framebuffer.GetColorBufferAddress()); + u32* color_buffer = (u32*)Memory::GetPointer(PAddrToVAddr(registers.framebuffer.GetColorBufferPhysicalAddress())); u32 value = (color.a() << 24) | (color.r() << 16) | (color.g() << 8) | color.b(); // Assuming RGBA8 format until actual framebuffer format handling is implemented @@ -26,14 +26,14 @@ static void DrawPixel(int x, int y, const Math::Vec4& color) { } static u32 GetDepth(int x, int y) { - u16* depth_buffer = (u16*)Memory::GetPointer(registers.framebuffer.GetDepthBufferAddress()); + u16* depth_buffer = (u16*)Memory::GetPointer(PAddrToVAddr(registers.framebuffer.GetDepthBufferPhysicalAddress())); // Assuming 16-bit depth buffer format until actual format handling is implemented return *(depth_buffer + x + y * registers.framebuffer.GetWidth()); } static void SetDepth(int x, int y, u16 value) { - u16* depth_buffer = (u16*)Memory::GetPointer(registers.framebuffer.GetDepthBufferAddress()); + u16* depth_buffer = (u16*)Memory::GetPointer(PAddrToVAddr(registers.framebuffer.GetDepthBufferPhysicalAddress())); // Assuming 16-bit depth buffer format until actual format handling is implemented *(depth_buffer + x + y * registers.framebuffer.GetWidth()) = value; @@ -204,7 +204,7 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0, s = GetWrappedTexCoord(registers.texture0.wrap_s, s, registers.texture0.width); t = GetWrappedTexCoord(registers.texture0.wrap_t, t, registers.texture0.height); - u8* texture_data = Memory::GetPointer(texture.config.GetPhysicalAddress()); + u8* texture_data = Memory::GetPointer(PAddrToVAddr(texture.config.GetPhysicalAddress())); auto info = DebugUtils::TextureInfo::FromPicaRegister(texture.config, texture.format); texture_color[i] = DebugUtils::LookupTexture(texture_data, s, t, info); -- cgit v1.2.3 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(-) (limited to 'src/video_core/debug_utils') diff --git a/src/citra_qt/debugger/graphics_cmdlists.cpp b/src/citra_qt/debugger/graphics_cmdlists.cpp index bf35f035f..95187e54d 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 08ecd4ccb..1a7b851d5 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 7d82d733d..583614328 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 From 79c29243ed94fb247dfa5a60e1863a8f64f11669 Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Wed, 10 Dec 2014 17:31:50 +0100 Subject: Pica/DebugUtils: Add an event triggered after loading a vertex. --- src/citra_qt/debugger/graphics_breakpoints.cpp | 1 + src/video_core/command_processor.cpp | 3 +++ src/video_core/debug_utils/debug_utils.h | 1 + 3 files changed, 5 insertions(+) (limited to 'src/video_core/debug_utils') diff --git a/src/citra_qt/debugger/graphics_breakpoints.cpp b/src/citra_qt/debugger/graphics_breakpoints.cpp index 469c3e268..4cb41db22 100644 --- a/src/citra_qt/debugger/graphics_breakpoints.cpp +++ b/src/citra_qt/debugger/graphics_breakpoints.cpp @@ -44,6 +44,7 @@ QVariant BreakPointModel::data(const QModelIndex& index, int role) const { Pica::DebugContext::Event::CommandProcessed, tr("Pica command processed") }, { Pica::DebugContext::Event::IncomingPrimitiveBatch, tr("Incoming primitive batch") }, { Pica::DebugContext::Event::FinishedPrimitiveBatch, tr("Finished primitive batch") }, + { Pica::DebugContext::Event::VertexLoaded, tr("Vertex Loaded") } }; _dbg_assert_(Debug_GPU, map.size() == static_cast(Pica::DebugContext::Event::NumEvents)); diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp index d8bddd569..4f82694fd 100644 --- a/src/video_core/command_processor.cpp +++ b/src/video_core/command_processor.cpp @@ -131,6 +131,9 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) { } } + if (g_debug_context) + g_debug_context->OnEvent(DebugContext::Event::VertexLoaded, (void*)&input); + // NOTE: When dumping geometry, we simply assume that the first input attribute // corresponds to the position for now. DebugUtils::GeometryDumper::Vertex dumped_vertex = { diff --git a/src/video_core/debug_utils/debug_utils.h b/src/video_core/debug_utils/debug_utils.h index 2a764e121..f9be90115 100644 --- a/src/video_core/debug_utils/debug_utils.h +++ b/src/video_core/debug_utils/debug_utils.h @@ -26,6 +26,7 @@ public: CommandProcessed, IncomingPrimitiveBatch, FinishedPrimitiveBatch, + VertexLoaded, NumEvents }; -- cgit v1.2.3 From cc5746abfe838fa130dd8be58219e00ae292a8fe Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Tue, 16 Dec 2014 01:12:29 +0100 Subject: Pica/DebugUtils: Replace duplicated SHBIN structures in favor of nihstro's ones. --- src/video_core/debug_utils/debug_utils.cpp | 69 ++++-------------------------- 1 file changed, 8 insertions(+), 61 deletions(-) (limited to 'src/video_core/debug_utils') diff --git a/src/video_core/debug_utils/debug_utils.cpp b/src/video_core/debug_utils/debug_utils.cpp index 1a7b851d5..7e1cfb92c 100644 --- a/src/video_core/debug_utils/debug_utils.cpp +++ b/src/video_core/debug_utils/debug_utils.cpp @@ -14,6 +14,8 @@ #include #endif +#include + #include "common/log.h" #include "common/file_util.h" @@ -22,6 +24,10 @@ #include "debug_utils.h" +using nihstro::DVLBHeader; +using nihstro::DVLEHeader; +using nihstro::DVLPHeader; + namespace Pica { void DebugContext::OnEvent(Event event, void* data) { @@ -98,65 +104,6 @@ void GeometryDumper::Dump() { } } -#pragma pack(1) -struct DVLBHeader { - enum : u32 { - MAGIC_WORD = 0x424C5644, // "DVLB" - }; - - u32 magic_word; - u32 num_programs; -// u32 dvle_offset_table[]; -}; -static_assert(sizeof(DVLBHeader) == 0x8, "Incorrect structure size"); - -struct DVLPHeader { - enum : u32 { - MAGIC_WORD = 0x504C5644, // "DVLP" - }; - - u32 magic_word; - u32 version; - u32 binary_offset; // relative to DVLP start - u32 binary_size_words; - u32 swizzle_patterns_offset; - u32 swizzle_patterns_num_entries; - u32 unk2; -}; -static_assert(sizeof(DVLPHeader) == 0x1C, "Incorrect structure size"); - -struct DVLEHeader { - enum : u32 { - MAGIC_WORD = 0x454c5644, // "DVLE" - }; - - enum class ShaderType : u8 { - VERTEX = 0, - GEOMETRY = 1, - }; - - u32 magic_word; - u16 pad1; - ShaderType type; - u8 pad2; - u32 main_offset_words; // offset within binary blob - u32 endmain_offset_words; - u32 pad3; - u32 pad4; - u32 constant_table_offset; - u32 constant_table_size; // number of entries - u32 label_table_offset; - u32 label_table_size; - u32 output_register_table_offset; - u32 output_register_table_size; - u32 uniform_table_offset; - u32 uniform_table_size; - u32 symbol_table_offset; - u32 symbol_table_size; - -}; -static_assert(sizeof(DVLEHeader) == 0x40, "Incorrect structure size"); -#pragma pack() void DumpShader(const u32* binary_data, u32 binary_size, const u32* swizzle_data, u32 swizzle_size, u32 main_offset, const Regs::VSOutputAttributes* output_attributes) @@ -276,8 +223,8 @@ void DumpShader(const u32* binary_data, u32 binary_size, const u32* swizzle_data dvlp.binary_size_words = binary_size; QueueForWriting((u8*)binary_data, binary_size * sizeof(u32)); - dvlp.swizzle_patterns_offset = write_offset - dvlp_offset; - dvlp.swizzle_patterns_num_entries = swizzle_size; + dvlp.swizzle_info_offset = write_offset - dvlp_offset; + dvlp.swizzle_info_num_entries = swizzle_size; u32 dummy = 0; for (unsigned int i = 0; i < swizzle_size; ++i) { QueueForWriting((u8*)&swizzle_data[i], sizeof(swizzle_data[i])); -- cgit v1.2.3 From d81370682fccda1370ba22026aa21a260b506efd Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Fri, 19 Dec 2014 18:49:09 +0100 Subject: Pica/DebugUtils: Make a number of variables static. Makes for cleaner and faster code. --- src/video_core/debug_utils/debug_utils.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'src/video_core/debug_utils') diff --git a/src/video_core/debug_utils/debug_utils.cpp b/src/video_core/debug_utils/debug_utils.cpp index 7e1cfb92c..0085c117d 100644 --- a/src/video_core/debug_utils/debug_utils.cpp +++ b/src/video_core/debug_utils/debug_utils.cpp @@ -580,7 +580,7 @@ void DumpTevStageConfig(const std::array& stages) for (size_t index = 0; index < stages.size(); ++index) { const auto& tev_stage = stages[index]; - const std::map source_map = { + static const std::map source_map = { { Source::PrimaryColor, "PrimaryColor" }, { Source::Texture0, "Texture0" }, { Source::Texture1, "Texture1" }, @@ -589,23 +589,23 @@ void DumpTevStageConfig(const std::array& stages) { Source::Previous, "Previous" }, }; - const std::map color_modifier_map = { + static const std::map color_modifier_map = { { ColorModifier::SourceColor, { "%source.rgb" } }, { ColorModifier::SourceAlpha, { "%source.aaa" } }, }; - const std::map alpha_modifier_map = { + static const std::map alpha_modifier_map = { { AlphaModifier::SourceAlpha, "%source.a" }, { AlphaModifier::OneMinusSourceAlpha, "(255 - %source.a)" }, }; - std::map combiner_map = { + static const std::map combiner_map = { { Operation::Replace, "%source1" }, { Operation::Modulate, "(%source1 * %source2) / 255" }, { Operation::Add, "(%source1 + %source2)" }, { Operation::Lerp, "lerp(%source1, %source2, %source3)" }, }; - auto ReplacePattern = + static auto ReplacePattern = [](const std::string& input, const std::string& pattern, const std::string& replacement) -> std::string { size_t start = input.find(pattern); if (start == std::string::npos) @@ -615,8 +615,8 @@ void DumpTevStageConfig(const std::array& stages) ret.replace(start, pattern.length(), replacement); return ret; }; - auto GetColorSourceStr = - [&source_map,&color_modifier_map,&ReplacePattern](const Source& src, const ColorModifier& modifier) { + static auto GetColorSourceStr = + [](const Source& src, const ColorModifier& modifier) { auto src_it = source_map.find(src); std::string src_str = "Unknown"; if (src_it != source_map.end()) @@ -629,8 +629,8 @@ void DumpTevStageConfig(const std::array& stages) return ReplacePattern(modifier_str, "%source", src_str); }; - auto GetColorCombinerStr = - [&](const Regs::TevStageConfig& tev_stage) { + static auto GetColorCombinerStr = + [](const Regs::TevStageConfig& tev_stage) { auto op_it = combiner_map.find(tev_stage.color_op); std::string op_str = "Unknown op (%source1, %source2, %source3)"; if (op_it != combiner_map.end()) @@ -640,8 +640,8 @@ void DumpTevStageConfig(const std::array& stages) op_str = ReplacePattern(op_str, "%source2", GetColorSourceStr(tev_stage.color_source2, tev_stage.color_modifier2)); return ReplacePattern(op_str, "%source3", GetColorSourceStr(tev_stage.color_source3, tev_stage.color_modifier3)); }; - auto GetAlphaSourceStr = - [&source_map,&alpha_modifier_map,&ReplacePattern](const Source& src, const AlphaModifier& modifier) { + static auto GetAlphaSourceStr = + [](const Source& src, const AlphaModifier& modifier) { auto src_it = source_map.find(src); std::string src_str = "Unknown"; if (src_it != source_map.end()) @@ -654,8 +654,8 @@ void DumpTevStageConfig(const std::array& stages) return ReplacePattern(modifier_str, "%source", src_str); }; - auto GetAlphaCombinerStr = - [&](const Regs::TevStageConfig& tev_stage) { + static auto GetAlphaCombinerStr = + [](const Regs::TevStageConfig& tev_stage) { auto op_it = combiner_map.find(tev_stage.alpha_op); std::string op_str = "Unknown op (%source1, %source2, %source3)"; if (op_it != combiner_map.end()) -- cgit v1.2.3 From 6e275778c9e7e55cabadb14fdabaa51a55348663 Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Fri, 19 Dec 2014 19:15:47 +0100 Subject: Pica/DebugUtils: Better document LookupTexture. --- src/video_core/debug_utils/debug_utils.cpp | 12 ++++++------ src/video_core/debug_utils/debug_utils.h | 11 ++++++++++- 2 files changed, 16 insertions(+), 7 deletions(-) (limited to 'src/video_core/debug_utils') diff --git a/src/video_core/debug_utils/debug_utils.cpp b/src/video_core/debug_utils/debug_utils.cpp index 0085c117d..1c08ba350 100644 --- a/src/video_core/debug_utils/debug_utils.cpp +++ b/src/video_core/debug_utils/debug_utils.cpp @@ -392,8 +392,10 @@ const Math::Vec4 LookupTexture(const u8* source, int x, int y, const Texture { const u8* source_ptr = source + coarse_x * block_height * 2 + coarse_y * info.stride + texel_index_within_tile * 2; - // TODO: Better control this... + // TODO: compoent order not verified + if (disable_alpha) { + // Show intensity as red, alpha as green return { *source_ptr, *(source_ptr+1), 0, 255 }; } else { return { *source_ptr, *source_ptr, *source_ptr, *(source_ptr+1)}; @@ -403,8 +405,6 @@ const Math::Vec4 LookupTexture(const u8* source, int x, int y, const Texture 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 }; } @@ -412,7 +412,6 @@ const Math::Vec4 LookupTexture(const u8* source, int x, int y, const Texture { const u8* source_ptr = source + coarse_x * block_height + coarse_y * info.stride + texel_index_within_tile; - // TODO: Better control this... if (disable_alpha) { return { *source_ptr, *source_ptr, *source_ptr, 255 }; } else { @@ -424,14 +423,15 @@ const Math::Vec4 LookupTexture(const u8* source, int x, int y, const Texture { const u8* source_ptr = source + coarse_x * block_height / 2 + coarse_y * info.stride + texel_index_within_tile / 2; - // TODO: Order? + // TODO: compoent order not verified + u8 i = (*source_ptr)&0xF; u8 a = ((*source_ptr) & 0xF0) >> 4; a |= a << 4; i |= i << 4; - // TODO: Better control this... if (disable_alpha) { + // Show intensity as red, alpha as green return { i, a, 0, 255 }; } else { return { i, i, i, a }; diff --git a/src/video_core/debug_utils/debug_utils.h b/src/video_core/debug_utils/debug_utils.h index f9be90115..f361a5385 100644 --- a/src/video_core/debug_utils/debug_utils.h +++ b/src/video_core/debug_utils/debug_utils.h @@ -203,8 +203,17 @@ struct TextureInfo { const Pica::Regs::TextureFormat& format); }; -const Math::Vec4 LookupTexture(const u8* source, int x, int y, const TextureInfo& info, +/** + * Lookup texel located at the given coordinates and return an RGBA vector of its color. + * @param source Source pointer to read data from + * @param s,t Texture coordinates to read from + * @param info TextureInfo object describing the texture setup + * @param disable_alpha This is used for debug widgets which use this method to display textures without providing a good way to visualize alpha by themselves. If true, this will return 255 for the alpha component, and either drop the information entirely or store it in an "unused" color channel. + * @todo Eventually we should get rid of the disable_alpha parameter. + */ +const Math::Vec4 LookupTexture(const u8* source, int s, int t, const TextureInfo& info, bool disable_alpha = false); + void DumpTexture(const Pica::Regs::TextureConfig& texture_config, u8* data); void DumpTevStageConfig(const std::array& stages); -- cgit v1.2.3 From 88e9efe4b8b370a93bae688dcbe3c03eda905379 Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Fri, 19 Dec 2014 19:20:02 +0100 Subject: Pica/DebugUtils: Fix two warnings. --- src/video_core/debug_utils/debug_utils.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/video_core/debug_utils') diff --git a/src/video_core/debug_utils/debug_utils.cpp b/src/video_core/debug_utils/debug_utils.cpp index 1c08ba350..d9fed58bf 100644 --- a/src/video_core/debug_utils/debug_utils.cpp +++ b/src/video_core/debug_utils/debug_utils.cpp @@ -346,7 +346,7 @@ const Math::Vec4 LookupTexture(const u8* source, int x, int y, const Texture case Regs::TextureFormat::RGBA8: { const u8* source_ptr = source + coarse_x * block_height * 4 + coarse_y * info.stride + texel_index_within_tile * 4; - return { source_ptr[3], source_ptr[2], source_ptr[1], disable_alpha ? 255 : source_ptr[0] }; + return { source_ptr[3], source_ptr[2], source_ptr[1], disable_alpha ? (u8)255 : source_ptr[0] }; } case Regs::TextureFormat::RGB8: @@ -385,7 +385,7 @@ const Math::Vec4 LookupTexture(const u8* source, int x, int y, const Texture g = (g << 4) | g; b = (b << 4) | b; a = (a << 4) | a; - return { r, g, b, disable_alpha ? 255 : a }; + return { r, g, b, disable_alpha ? (u8)255 : a }; } case Regs::TextureFormat::IA8: -- cgit v1.2.3 From 871418e62b079a83d9121dca0ef75b91acbe77cd Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Fri, 19 Dec 2014 19:37:37 +0100 Subject: Pica/DebugUtils: Further cleanups to LookupTexture. --- src/video_core/debug_utils/debug_utils.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/video_core/debug_utils') diff --git a/src/video_core/debug_utils/debug_utils.cpp b/src/video_core/debug_utils/debug_utils.cpp index d9fed58bf..328386b7e 100644 --- a/src/video_core/debug_utils/debug_utils.cpp +++ b/src/video_core/debug_utils/debug_utils.cpp @@ -392,13 +392,13 @@ const Math::Vec4 LookupTexture(const u8* source, int x, int y, const Texture { const u8* source_ptr = source + coarse_x * block_height * 2 + coarse_y * info.stride + texel_index_within_tile * 2; - // TODO: compoent order not verified + // TODO: component order not verified if (disable_alpha) { // Show intensity as red, alpha as green - return { *source_ptr, *(source_ptr+1), 0, 255 }; + return { source_ptr[0], source_ptr[1], 0, 255 }; } else { - return { *source_ptr, *source_ptr, *source_ptr, *(source_ptr+1)}; + return { source_ptr[0], source_ptr[0], source_ptr[0], source_ptr[1]}; } } @@ -423,9 +423,9 @@ const Math::Vec4 LookupTexture(const u8* source, int x, int y, const Texture { const u8* source_ptr = source + coarse_x * block_height / 2 + coarse_y * info.stride + texel_index_within_tile / 2; - // TODO: compoent order not verified + // TODO: component order not verified - u8 i = (*source_ptr)&0xF; + u8 i = (*source_ptr) & 0xF; u8 a = ((*source_ptr) & 0xF0) >> 4; a |= a << 4; i |= i << 4; @@ -442,11 +442,11 @@ const Math::Vec4 LookupTexture(const u8* source, int x, int y, const Texture { const u8* source_ptr = source + coarse_x * block_height / 2 + coarse_y * info.stride + texel_index_within_tile / 2; - // TODO: Order? + // TODO: component order not verified + 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 { -- cgit v1.2.3