mirror of
https://github.com/gopher64/gopher64.git
synced 2026-09-03 19:25:23 +02:00
sync parallel rdp for texture images (#361)
* sync parallel rdp for texture images * more * more * more * more * more
This commit is contained in:
+82
-34
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user