sync parallel rdp for texture images (#361)

* sync parallel rdp for texture images

* more

* more

* more

* more

* more
This commit is contained in:
Logan McNaughton
2025-04-02 12:24:30 +02:00
committed by GitHub
parent 82b1888f82
commit b4832b941f
+82 -34
View File
@@ -56,12 +56,12 @@ typedef struct
{
uint32_t depthbuffer_address;
uint32_t framebuffer_address;
uint32_t texture_address;
uint32_t framebuffer_pixel_size;
uint32_t framebuffer_width;
uint32_t texture_pixel_size;
uint32_t texture_width;
uint32_t framebuffer_height;
uint32_t framebuffer_size;
uint32_t depthbuffer_size;
uint8_t depthbuffer_enabled;
} FrameBufferInfo;
typedef struct
@@ -492,24 +492,45 @@ void rdp_load_state(const uint8_t *state)
memcpy(&rdp_device, state, sizeof(RDP_DEVICE));
}
void calculate_buffer_size()
uint32_t texture_size(uint32_t area)
{
switch (rdp_device.frame_buffer_info.texture_pixel_size)
{
case 0:
return (area / 2) >> 3;
case 1:
return (area) >> 3;
case 2:
return (area * 2) >> 3;
case 3:
return (area * 4) >> 3;
default:
printf("Invalid texture pixel size: %u\n", rdp_device.frame_buffer_info.texture_pixel_size);
return 0;
}
}
uint32_t framebuffer_size()
{
switch (rdp_device.frame_buffer_info.framebuffer_pixel_size)
{
case 0:
rdp_device.frame_buffer_info.framebuffer_size = (rdp_device.frame_buffer_info.framebuffer_width * rdp_device.frame_buffer_info.framebuffer_height / 2) >> 3;
break;
return (rdp_device.frame_buffer_info.framebuffer_width * rdp_device.frame_buffer_info.framebuffer_height / 2) >> 3;
case 1:
rdp_device.frame_buffer_info.framebuffer_size = (rdp_device.frame_buffer_info.framebuffer_width * rdp_device.frame_buffer_info.framebuffer_height) >> 3;
break;
return (rdp_device.frame_buffer_info.framebuffer_width * rdp_device.frame_buffer_info.framebuffer_height) >> 3;
case 2:
rdp_device.frame_buffer_info.framebuffer_size = (rdp_device.frame_buffer_info.framebuffer_width * rdp_device.frame_buffer_info.framebuffer_height * 2) >> 3;
break;
return (rdp_device.frame_buffer_info.framebuffer_width * rdp_device.frame_buffer_info.framebuffer_height * 2) >> 3;
case 3:
rdp_device.frame_buffer_info.framebuffer_size = (rdp_device.frame_buffer_info.framebuffer_width * rdp_device.frame_buffer_info.framebuffer_height * 4) >> 3;
break;
return (rdp_device.frame_buffer_info.framebuffer_width * rdp_device.frame_buffer_info.framebuffer_height * 4) >> 3;
default:
printf("Invalid framebuffer pixel size: %u\n", rdp_device.frame_buffer_info.framebuffer_pixel_size);
return 0;
}
rdp_device.frame_buffer_info.depthbuffer_size = (rdp_device.frame_buffer_info.framebuffer_width * rdp_device.frame_buffer_info.framebuffer_height * 2) >> 3;
}
uint32_t depthbuffer_size()
{
return (rdp_device.frame_buffer_info.framebuffer_width * rdp_device.frame_buffer_info.framebuffer_height * 2) >> 3;
}
uint64_t rdp_process_commands()
@@ -573,37 +594,64 @@ uint64_t rdp_process_commands()
if (command >= 8)
processor->enqueue_command(cmd_length * 2, &rdp_device.cmd_data[2 * rdp_device.cmd_cur]);
if ((RDP::Op(command) >= RDP::Op::FillTriangle && RDP::Op(command) <= RDP::Op::ShadeTextureZBufferTriangle) ||
RDP::Op(command) == RDP::Op::TextureRectangle ||
RDP::Op(command) == RDP::Op::TextureRectangleFlip ||
RDP::Op(command) == RDP::Op::FillRectangle)
switch (RDP::Op(command))
{
case RDP::Op::FillTriangle:
case RDP::Op::FillZBufferTriangle:
case RDP::Op::TextureTriangle:
case RDP::Op::TextureZBufferTriangle:
case RDP::Op::ShadeTriangle:
case RDP::Op::ShadeZBufferTriangle:
case RDP::Op::ShadeTextureTriangle:
case RDP::Op::ShadeTextureZBufferTriangle:
case RDP::Op::TextureRectangle:
case RDP::Op::TextureRectangleFlip:
case RDP::Op::FillRectangle:
if (!rdram_dirty[rdp_device.frame_buffer_info.framebuffer_address])
{
std::fill_n(rdram_dirty.begin() + rdp_device.frame_buffer_info.framebuffer_address, rdp_device.frame_buffer_info.framebuffer_size, true);
std::fill_n(rdram_dirty.begin() + rdp_device.frame_buffer_info.framebuffer_address, framebuffer_size(), true);
}
if (rdp_device.frame_buffer_info.depthbuffer_enabled && !rdram_dirty[rdp_device.frame_buffer_info.depthbuffer_address])
if (rdp_device.frame_buffer_info.depthbuffer_address < rdram_dirty.size() && !rdram_dirty[rdp_device.frame_buffer_info.depthbuffer_address])
{
std::fill_n(rdram_dirty.begin() + rdp_device.frame_buffer_info.depthbuffer_address, rdp_device.frame_buffer_info.depthbuffer_size, true);
std::fill_n(rdram_dirty.begin() + rdp_device.frame_buffer_info.depthbuffer_address, depthbuffer_size(), true);
}
}
else if (RDP::Op(command) == RDP::Op::SetOtherModes)
break;
case RDP::Op::LoadTLut:
case RDP::Op::LoadTile:
if (!rdram_dirty[rdp_device.frame_buffer_info.texture_address])
{
uint32_t lower_right_t = (w2 & 0xFFF) >> 2;
std::fill_n(rdram_dirty.begin() +
rdp_device.frame_buffer_info.texture_address,
texture_size(rdp_device.frame_buffer_info.texture_width * lower_right_t), true);
}
break;
case RDP::Op::LoadBlock:
{
rdp_device.frame_buffer_info.depthbuffer_enabled = (w2 >> 5) & 1;
uint32_t upper_left_s = ((w1 >> 12) & 0xFFF) >> 2;
uint32_t offset_address = rdp_device.frame_buffer_info.texture_address + texture_size(upper_left_s);
if (!rdram_dirty[offset_address])
{
uint32_t lower_right_s = ((w2 >> 12) & 0xFFF) >> 2;
std::fill_n(rdram_dirty.begin() + offset_address, texture_size(lower_right_s - upper_left_s), true);
}
break;
}
else if (RDP::Op(command) == RDP::Op::SetColorImage)
{
case RDP::Op::SetColorImage:
rdp_device.frame_buffer_info.framebuffer_address = (w2 & 0x00FFFFFF) >> 3;
rdp_device.frame_buffer_info.framebuffer_pixel_size = (w1 >> 19) & 0x3;
rdp_device.frame_buffer_info.framebuffer_width = (w1 & 0x3FF) + 1;
calculate_buffer_size();
}
else if (RDP::Op(command) == RDP::Op::SetMaskImage)
{
break;
case RDP::Op::SetMaskImage:
rdp_device.frame_buffer_info.depthbuffer_address = (w2 & 0x00FFFFFF) >> 3;
}
else if (RDP::Op(command) == RDP::Op::SetScissor)
break;
case RDP::Op::SetTextureImage:
rdp_device.frame_buffer_info.texture_address = (w2 & 0x00FFFFFF) >> 3;
rdp_device.frame_buffer_info.texture_pixel_size = (w1 >> 19) & 0x3;
rdp_device.frame_buffer_info.texture_width = (w1 & 0x3FF) + 1;
break;
case RDP::Op::SetScissor:
{
uint32_t upper_left_x = ((w1 >> 12) & 0xFFF) >> 2;
uint32_t upper_left_y = (w1 & 0xFFF) >> 2;
@@ -619,14 +667,14 @@ uint64_t rdp_process_commands()
}
rdp_device.frame_buffer_info.framebuffer_height = lower_right_y;
calculate_buffer_size();
break;
}
else if (RDP::Op(command) == RDP::Op::SyncFull)
{
case RDP::Op::SyncFull:
sync_signal = processor->signal_timeline();
interrupt_timer = rdp_device.region;
if (interrupt_timer == 0)
interrupt_timer = 5000;
break;
}
rdp_device.cmd_cur += cmd_length;