From c564c21668912b803947adddc166ff1315b218e4 Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 23 Feb 2015 18:24:35 -0500 Subject: GPU: Implemented bits 3 and 1 from the display transfer flags. Bit 3 is used to specify a raw copy, where no processing is done to the data, seems to behave exactly as a DMA. Bit 1 is used to specify whether to convert from a tiled format to a linear format or viceversa. --- src/video_core/rasterizer.cpp | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) (limited to 'src/video_core/rasterizer.cpp') diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp index 24dc3785..a7bb0612 100644 --- a/src/video_core/rasterizer.cpp +++ b/src/video_core/rasterizer.cpp @@ -7,13 +7,14 @@ #include "common/common_types.h" #include "common/math_util.h" +#include "core/hw/gpu.h" +#include "debug_utils/debug_utils.h" #include "math.h" #include "color.h" #include "pica.h" #include "rasterizer.h" #include "vertex_shader.h" - -#include "debug_utils/debug_utils.h" +#include "video_core/utils.h" namespace Pica { @@ -27,10 +28,14 @@ static void DrawPixel(int x, int y, const Math::Vec4& color) { // NOTE: The framebuffer height register contains the actual FB height minus one. y = (registers.framebuffer.height - y); + const u32 coarse_y = y & ~7; + u32 bytes_per_pixel = GPU::Regs::BytesPerPixel(GPU::Regs::PixelFormat(registers.framebuffer.color_format.Value())); + u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * registers.framebuffer.width * bytes_per_pixel; + switch (registers.framebuffer.color_format) { case registers.framebuffer.RGBA8: { - u8* pixel = color_buffer + (x + y * registers.framebuffer.GetWidth()) * 4; + u8* pixel = color_buffer + dst_offset; pixel[3] = color.r(); pixel[2] = color.g(); pixel[1] = color.b(); @@ -40,14 +45,14 @@ static void DrawPixel(int x, int y, const Math::Vec4& color) { case registers.framebuffer.RGBA4: { - u8* pixel = color_buffer + (x + y * registers.framebuffer.GetWidth()) * 2; + u8* pixel = color_buffer + dst_offset; pixel[1] = (color.r() & 0xF0) | (color.g() >> 4); pixel[0] = (color.b() & 0xF0) | (color.a() >> 4); break; } default: - LOG_CRITICAL(Render_Software, "Unknown framebuffer color format %x", registers.framebuffer.color_format); + LOG_CRITICAL(Render_Software, "Unknown framebuffer color format %x", registers.framebuffer.color_format.Value()); UNIMPLEMENTED(); } } @@ -58,11 +63,15 @@ static const Math::Vec4 GetPixel(int x, int y) { y = (registers.framebuffer.height - y); + const u32 coarse_y = y & ~7; + u32 bytes_per_pixel = GPU::Regs::BytesPerPixel(GPU::Regs::PixelFormat(registers.framebuffer.color_format.Value())); + u32 src_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * registers.framebuffer.width * bytes_per_pixel; + switch (registers.framebuffer.color_format) { case registers.framebuffer.RGBA8: { Math::Vec4 ret; - u8* pixel = color_buffer + (x + y * registers.framebuffer.GetWidth()) * 4; + u8* pixel = color_buffer + src_offset; ret.r() = pixel[3]; ret.g() = pixel[2]; ret.b() = pixel[1]; @@ -73,7 +82,7 @@ static const Math::Vec4 GetPixel(int x, int y) { case registers.framebuffer.RGBA4: { Math::Vec4 ret; - u8* pixel = color_buffer + (x + y * registers.framebuffer.GetWidth()) * 2; + u8* pixel = color_buffer + src_offset; ret.r() = Color::Convert4To8(pixel[1] >> 4); ret.g() = Color::Convert4To8(pixel[1] & 0x0F); ret.b() = Color::Convert4To8(pixel[0] >> 4); @@ -82,7 +91,7 @@ static const Math::Vec4 GetPixel(int x, int y) { } default: - LOG_CRITICAL(Render_Software, "Unknown framebuffer color format %x", registers.framebuffer.color_format); + LOG_CRITICAL(Render_Software, "Unknown framebuffer color format %x", registers.framebuffer.color_format.Value()); UNIMPLEMENTED(); } @@ -91,22 +100,28 @@ static const Math::Vec4 GetPixel(int x, int y) { static u32 GetDepth(int x, int y) { const PAddr addr = registers.framebuffer.GetDepthBufferPhysicalAddress(); - u16* depth_buffer = reinterpret_cast(Memory::GetPointer(PAddrToVAddr(addr))); + u8* depth_buffer = Memory::GetPointer(PAddrToVAddr(addr)); y = (registers.framebuffer.height - y); + + const u32 coarse_y = y & ~7; + u32 stride = registers.framebuffer.width * 2; // Assuming 16-bit depth buffer format until actual format handling is implemented - return *(depth_buffer + x + y * registers.framebuffer.GetWidth()); + return *(u16*)(depth_buffer + VideoCore::GetMortonOffset(x, y, 2) + coarse_y * stride); } static void SetDepth(int x, int y, u16 value) { const PAddr addr = registers.framebuffer.GetDepthBufferPhysicalAddress(); - u16* depth_buffer = reinterpret_cast(Memory::GetPointer(PAddrToVAddr(addr))); + u8* depth_buffer = Memory::GetPointer(PAddrToVAddr(addr)); y = (registers.framebuffer.height - y); + const u32 coarse_y = y & ~7; + u32 stride = registers.framebuffer.width * 2; + // Assuming 16-bit depth buffer format until actual format handling is implemented - *(depth_buffer + x + y * registers.framebuffer.GetWidth()) = value; + *(u16*)(depth_buffer + VideoCore::GetMortonOffset(x, y, 2) + coarse_y * stride) = value; } // NOTE: Assuming that rasterizer coordinates are 12.4 fixed-point values -- cgit v1.2.3