This commit is contained in:
Anon 2016-07-30 10:23:00 -05:00
parent 9535169577
commit 3be6948ca4

View File

@ -35,21 +35,21 @@
namespace GPU { namespace GPU {
Regs g_regs; Regs g_regs;
/// True if the current frame was skipped /// True if the current frame was skipped
bool g_skip_frame; bool g_skip_frame;
/// 268MHz CPU clocks / 60Hz frames per second /// 268MHz CPU clocks / 60Hz frames per second
const u64 frame_ticks = 268123480ull / 60; const u64 frame_ticks = 268123480ull / 60;
/// Event id for CoreTiming /// Event id for CoreTiming
static int vblank_event; static int vblank_event;
/// Total number of frames drawn /// Total number of frames drawn
static u64 frame_count; static u64 frame_count;
/// True if the last frame was skipped /// True if the last frame was skipped
static bool last_skip_frame; static bool last_skip_frame;
template <typename T> template <typename T>
inline void Read(T &var, const u32 raw_addr) { inline void Read(T &var, const u32 raw_addr) {
u32 addr = raw_addr - HW::VADDR_GPU; u32 addr = raw_addr - HW::VADDR_GPU;
u32 index = addr / 4; u32 index = addr / 4;
@ -60,9 +60,9 @@ namespace GPU {
} }
var = g_regs[addr / 4]; var = g_regs[addr / 4];
} }
static Math::Vec4<u8> DecodePixel(Regs::PixelFormat input_format, const u8* src_pixel) { static Math::Vec4<u8> DecodePixel(Regs::PixelFormat input_format, const u8* src_pixel) {
switch (input_format) { switch (input_format) {
case Regs::PixelFormat::RGBA8: case Regs::PixelFormat::RGBA8:
return Color::DecodeRGBA8(src_pixel); return Color::DecodeRGBA8(src_pixel);
@ -81,15 +81,15 @@ namespace GPU {
default: default:
LOG_ERROR(HW_GPU, "Unknown source framebuffer format %x", input_format); LOG_ERROR(HW_GPU, "Unknown source framebuffer format %x", input_format);
return{ 0, 0, 0, 0 }; return {0, 0, 0, 0};
}
} }
}
MICROPROFILE_DEFINE(GPU_DisplayTransfer, "GPU", "DisplayTransfer", MP_RGB(100, 100, 255)); MICROPROFILE_DEFINE(GPU_DisplayTransfer, "GPU", "DisplayTransfer", MP_RGB(100, 100, 255));
MICROPROFILE_DEFINE(GPU_CmdlistProcessing, "GPU", "Cmdlist Processing", MP_RGB(100, 255, 100)); MICROPROFILE_DEFINE(GPU_CmdlistProcessing, "GPU", "Cmdlist Processing", MP_RGB(100, 255, 100));
template <typename T> template <typename T>
inline void Write(u32 addr, const T data) { inline void Write(u32 addr, const T data) {
addr -= HW::VADDR_GPU; addr -= HW::VADDR_GPU;
u32 index = addr / 4; u32 index = addr / 4;
@ -134,8 +134,7 @@ namespace GPU {
ptr[1] = config.value_24bit_g; ptr[1] = config.value_24bit_g;
ptr[2] = config.value_24bit_b; ptr[2] = config.value_24bit_b;
} }
} } else if (config.fill_32bit) {
else if (config.fill_32bit) {
// fill with 32-bit values // fill with 32-bit values
if (end > start) { if (end > start) {
u32 value = config.value_32bit; u32 value = config.value_32bit;
@ -143,8 +142,7 @@ namespace GPU {
for (size_t i = 0; i < len; ++i) for (size_t i = 0; i < len; ++i)
memcpy(&start[i * sizeof(u32)], &value, sizeof(u32)); memcpy(&start[i * sizeof(u32)], &value, sizeof(u32));
} }
} } else {
else {
// fill with 16-bit values // fill with 16-bit values
u16 value_16bit = config.value_16bit.Value(); u16 value_16bit = config.value_16bit.Value();
for (u8* ptr = start; ptr < end; ptr += sizeof(u16)) for (u8* ptr = start; ptr < end; ptr += sizeof(u16))
@ -156,8 +154,7 @@ namespace GPU {
if (!is_second_filler) { if (!is_second_filler) {
GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PSC0); GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PSC0);
} } else {
else {
GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PSC1); GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PSC1);
} }
} }
@ -283,14 +280,12 @@ namespace GPU {
src_offset = (input_x + input_y * config.input_width) * src_bytes_per_pixel; src_offset = (input_x + input_y * config.input_width) * src_bytes_per_pixel;
dst_offset = VideoCore::GetMortonOffset(x, y, dst_bytes_per_pixel) + coarse_y * stride; dst_offset = VideoCore::GetMortonOffset(x, y, dst_bytes_per_pixel) + coarse_y * stride;
} } else {
else {
// Both input and output are linear // Both input and output are linear
src_offset = (input_x + input_y * config.input_width) * src_bytes_per_pixel; src_offset = (input_x + input_y * config.input_width) * src_bytes_per_pixel;
dst_offset = (x + y * output_width) * dst_bytes_per_pixel; dst_offset = (x + y * output_width) * dst_bytes_per_pixel;
} }
} } else {
else {
if (!config.dont_swizzle) { if (!config.dont_swizzle) {
// Interpret the input as tiled and the output as linear // Interpret the input as tiled and the output as linear
u32 coarse_y = input_y & ~7; u32 coarse_y = input_y & ~7;
@ -298,8 +293,7 @@ namespace GPU {
src_offset = VideoCore::GetMortonOffset(input_x, input_y, src_bytes_per_pixel) + coarse_y * stride; src_offset = VideoCore::GetMortonOffset(input_x, input_y, src_bytes_per_pixel) + coarse_y * stride;
dst_offset = (x + y * output_width) * dst_bytes_per_pixel; dst_offset = (x + y * output_width) * dst_bytes_per_pixel;
} } else {
else {
// Both input and output are tiled // Both input and output are tiled
u32 out_coarse_y = y & ~7; u32 out_coarse_y = y & ~7;
u32 out_stride = output_width * dst_bytes_per_pixel; u32 out_stride = output_width * dst_bytes_per_pixel;
@ -317,8 +311,7 @@ namespace GPU {
if (config.scaling == config.ScaleX) { if (config.scaling == config.ScaleX) {
Math::Vec4<u8> pixel = DecodePixel(config.input_format, src_pixel + src_bytes_per_pixel); Math::Vec4<u8> pixel = DecodePixel(config.input_format, src_pixel + src_bytes_per_pixel);
src_color = ((src_color + pixel) / 2).Cast<u8>(); src_color = ((src_color + pixel) / 2).Cast<u8>();
} } else if (config.scaling == config.ScaleXY) {
else if (config.scaling == config.ScaleXY) {
Math::Vec4<u8> pixel1 = DecodePixel(config.input_format, src_pixel + 1 * src_bytes_per_pixel); Math::Vec4<u8> pixel1 = DecodePixel(config.input_format, src_pixel + 1 * src_bytes_per_pixel);
Math::Vec4<u8> pixel2 = DecodePixel(config.input_format, src_pixel + 2 * src_bytes_per_pixel); Math::Vec4<u8> pixel2 = DecodePixel(config.input_format, src_pixel + 2 * src_bytes_per_pixel);
Math::Vec4<u8> pixel3 = DecodePixel(config.input_format, src_pixel + 3 * src_bytes_per_pixel); Math::Vec4<u8> pixel3 = DecodePixel(config.input_format, src_pixel + 3 * src_bytes_per_pixel);
@ -371,7 +364,8 @@ namespace GPU {
case GPU_REG_INDEX(command_processor_config.trigger): case GPU_REG_INDEX(command_processor_config.trigger):
{ {
const auto& config = g_regs.command_processor_config; const auto& config = g_regs.command_processor_config;
if (config.trigger & 1) { if (config.trigger & 1)
{
MICROPROFILE_SCOPE(GPU_CmdlistProcessing); MICROPROFILE_SCOPE(GPU_CmdlistProcessing);
u32* buffer = (u32*)Memory::GetPhysicalPointer(config.GetPhysicalAddress()); u32* buffer = (u32*)Memory::GetPhysicalPointer(config.GetPhysicalAddress());
@ -397,22 +391,22 @@ namespace GPU {
// addr + GPU VBase - IO VBase + IO PBase // addr + GPU VBase - IO VBase + IO PBase
Pica::g_debug_context->recorder->RegisterWritten<T>(addr + 0x1EF00000 - 0x1EC00000 + 0x10100000, data); Pica::g_debug_context->recorder->RegisterWritten<T>(addr + 0x1EF00000 - 0x1EC00000 + 0x10100000, data);
} }
} }
// Explicitly instantiate template functions because we aren't defining this in the header: // Explicitly instantiate template functions because we aren't defining this in the header:
template void Read<u64>(u64 &var, const u32 addr); template void Read<u64>(u64 &var, const u32 addr);
template void Read<u32>(u32 &var, const u32 addr); template void Read<u32>(u32 &var, const u32 addr);
template void Read<u16>(u16 &var, const u32 addr); template void Read<u16>(u16 &var, const u32 addr);
template void Read<u8>(u8 &var, const u32 addr); template void Read<u8>(u8 &var, const u32 addr);
template void Write<u64>(u32 addr, const u64 data); template void Write<u64>(u32 addr, const u64 data);
template void Write<u32>(u32 addr, const u32 data); template void Write<u32>(u32 addr, const u32 data);
template void Write<u16>(u32 addr, const u16 data); template void Write<u16>(u32 addr, const u16 data);
template void Write<u8>(u32 addr, const u8 data); template void Write<u8>(u32 addr, const u8 data);
/// Update hardware /// Update hardware
static void VBlankCallback(u64 userdata, int cycles_late) { static void VBlankCallback(u64 userdata, int cycles_late) {
frame_count++; frame_count++;
last_skip_frame = g_skip_frame; last_skip_frame = g_skip_frame;
g_skip_frame = (frame_count & Settings::values.frame_skip) != 0; g_skip_frame = (frame_count & Settings::values.frame_skip) != 0;
@ -438,10 +432,10 @@ namespace GPU {
// Reschedule recurrent event // Reschedule recurrent event
CoreTiming::ScheduleEvent(frame_ticks - cycles_late, vblank_event); CoreTiming::ScheduleEvent(frame_ticks - cycles_late, vblank_event);
} }
/// Initialize hardware /// Initialize hardware
void Init() { void Init() {
memset(&g_regs, 0, sizeof(g_regs)); memset(&g_regs, 0, sizeof(g_regs));
auto& framebuffer_top = g_regs.framebuffer_config[0]; auto& framebuffer_top = g_regs.framebuffer_config[0];
@ -478,11 +472,11 @@ namespace GPU {
CoreTiming::ScheduleEvent(frame_ticks, vblank_event); CoreTiming::ScheduleEvent(frame_ticks, vblank_event);
LOG_DEBUG(HW_GPU, "initialized OK"); LOG_DEBUG(HW_GPU, "initialized OK");
} }
/// Shutdown hardware /// Shutdown hardware
void Shutdown() { void Shutdown() {
LOG_DEBUG(HW_GPU, "shutdown OK"); LOG_DEBUG(HW_GPU, "shutdown OK");
} }
} // namespace } // namespace