mirror of
https://github.com/simple64/simple64.git
synced 2026-09-06 12:24:32 +02:00
update parallel rdp
This commit is contained in:
@@ -1 +1 @@
|
||||
e6cf0e5ca257135acbcacfbdacd7cd3fdf3fb408
|
||||
07c3d161dbeb78121be5eebdab7c810b72af822a
|
||||
|
||||
@@ -227,6 +227,11 @@ bool CommandProcessor::device_is_supported() const
|
||||
return is_supported;
|
||||
}
|
||||
|
||||
void CommandProcessor::set_validation_interface(ValidationInterface *iface)
|
||||
{
|
||||
renderer.set_validation_interface(iface);
|
||||
}
|
||||
|
||||
void CommandProcessor::clear_hidden_rdram()
|
||||
{
|
||||
clear_buffer(*hidden_rdram, 0x03030303);
|
||||
|
||||
@@ -124,6 +124,8 @@ public:
|
||||
|
||||
~CommandProcessor();
|
||||
|
||||
void set_validation_interface(ValidationInterface *iface);
|
||||
|
||||
bool device_is_supported() const;
|
||||
|
||||
// Synchronization.
|
||||
@@ -210,10 +212,10 @@ private:
|
||||
std::unique_ptr<ShaderBank> shader_bank;
|
||||
#endif
|
||||
|
||||
CommandRing ring;
|
||||
|
||||
VideoInterface vi;
|
||||
// Tear-down order is important here.
|
||||
Renderer renderer;
|
||||
VideoInterface vi;
|
||||
CommandRing ring;
|
||||
|
||||
void clear_hidden_rdram();
|
||||
void clear_tmem();
|
||||
|
||||
@@ -120,6 +120,11 @@ void Renderer::set_device(Vulkan::Device *device_)
|
||||
device = device_;
|
||||
}
|
||||
|
||||
void Renderer::set_validation_interface(ValidationInterface *iface)
|
||||
{
|
||||
validation_iface = iface;
|
||||
}
|
||||
|
||||
bool Renderer::init_caps()
|
||||
{
|
||||
auto &features = device->get_device_features();
|
||||
@@ -1404,8 +1409,50 @@ void Renderer::fixup_triangle_setup(TriangleSetup &setup) const
|
||||
setup.flags |= TRIANGLE_SETUP_FILL_COPY_RASTER_BIT;
|
||||
}
|
||||
|
||||
void Renderer::validate_draw_state() const
|
||||
{
|
||||
if ((stream.static_raster_state.flags & RASTERIZATION_FILL_BIT) != 0)
|
||||
{
|
||||
if (fb.fmt == FBFormat::I4)
|
||||
{
|
||||
validation_iface->report_rdp_crash(ValidationError::Fill4bpp,
|
||||
"Attempted to use Fill mode on 4bpp surface.");
|
||||
}
|
||||
|
||||
if ((stream.depth_blend_state.flags & DEPTH_BLEND_DEPTH_TEST_BIT) != 0)
|
||||
{
|
||||
validation_iface->report_rdp_crash(ValidationError::FillDepthTest,
|
||||
"Attempted to use Fill mode with depth test.");
|
||||
}
|
||||
|
||||
if ((stream.depth_blend_state.flags & DEPTH_BLEND_IMAGE_READ_ENABLE_BIT) != 0)
|
||||
{
|
||||
validation_iface->report_rdp_crash(ValidationError::FillImageReadEnable,
|
||||
"Attempted to use Fill mode with image read enable.");
|
||||
}
|
||||
|
||||
if ((stream.depth_blend_state.flags & DEPTH_BLEND_DEPTH_UPDATE_BIT) != 0 &&
|
||||
!constants.use_prim_depth)
|
||||
{
|
||||
validation_iface->report_rdp_crash(ValidationError::FillDepthWrite,
|
||||
"Attempted to use Fill mode with depth write enabled.");
|
||||
}
|
||||
}
|
||||
else if ((stream.static_raster_state.flags & RASTERIZATION_COPY_BIT) != 0)
|
||||
{
|
||||
if (fb.fmt == FBFormat::RGBA8888)
|
||||
{
|
||||
validation_iface->report_rdp_crash(ValidationError::Copy32bpp,
|
||||
"Attempted to use Copy mode on 32bpp surface.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer::draw_shaded_primitive(TriangleSetup &setup, const AttributeSetup &attr)
|
||||
{
|
||||
if (validation_iface)
|
||||
validate_draw_state();
|
||||
|
||||
fixup_triangle_setup(setup);
|
||||
|
||||
unsigned num_tiles = compute_conservative_max_num_tiles(setup);
|
||||
@@ -3040,6 +3087,15 @@ bool Renderer::tmem_upload_needs_flush(uint32_t addr) const
|
||||
|
||||
void Renderer::load_tile(uint32_t tile, const LoadTileInfo &info)
|
||||
{
|
||||
if (validation_iface && info.mode == UploadMode::TLUT)
|
||||
{
|
||||
if ((info.thi >> 2) > (info.tlo >> 2))
|
||||
{
|
||||
validation_iface->report_rdp_crash(ValidationError::InvalidMultilineLoadTlut,
|
||||
"Attempting to load multiple lines in TLUT.");
|
||||
}
|
||||
}
|
||||
|
||||
if (tmem_upload_needs_flush(info.tex_addr))
|
||||
flush_queues();
|
||||
|
||||
@@ -3171,6 +3227,8 @@ void Renderer::load_tile_iteration(uint32_t tile, const LoadTileInfo &info, uint
|
||||
if (info.size == TextureSize::Bpp4)
|
||||
{
|
||||
LOGE("4-bit VRAM pointer crashes the RDP.\n");
|
||||
if (validation_iface)
|
||||
validation_iface->report_rdp_crash(ValidationError::LoadTile4bpp, "4-bit VRAM pointer crashes the RDP.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -72,6 +72,28 @@ struct RendererOptions
|
||||
bool super_sampled_readback_dither = false;
|
||||
};
|
||||
|
||||
enum class ValidationError
|
||||
{
|
||||
Fill4bpp,
|
||||
LoadTile4bpp,
|
||||
InvalidMultilineLoadTlut,
|
||||
FillDepthTest,
|
||||
FillDepthWrite,
|
||||
FillImageReadEnable,
|
||||
Copy32bpp
|
||||
};
|
||||
|
||||
class ValidationInterface
|
||||
{
|
||||
public:
|
||||
virtual ~ValidationInterface() = default;
|
||||
// Validation errors may be called from a thread as errors are encountered.
|
||||
// Reports situations that would cause fatal error on a real RDP.
|
||||
// We only opt to report these situations rather than deliberately crashing the renderer.
|
||||
// Handling crashes is only relevant during development of N64 homebrew.
|
||||
virtual void report_rdp_crash(ValidationError err, const char *msg) = 0;
|
||||
};
|
||||
|
||||
class Renderer : public Vulkan::DebugChannelInterface
|
||||
{
|
||||
public:
|
||||
@@ -79,6 +101,8 @@ public:
|
||||
~Renderer();
|
||||
void set_device(Vulkan::Device *device);
|
||||
|
||||
void set_validation_interface(ValidationInterface *iface);
|
||||
|
||||
// If coherent is false, RDRAM is a buffer split into data in lower half and writemask state in upper half, each part being size large.
|
||||
// offset must be 0 in this case.
|
||||
void set_rdram(Vulkan::Buffer *buffer, uint8_t *host_rdram, size_t offset, size_t size, bool coherent);
|
||||
@@ -136,11 +160,14 @@ private:
|
||||
CommandProcessor &processor;
|
||||
Vulkan::Device *device = nullptr;
|
||||
Vulkan::Buffer *rdram = nullptr;
|
||||
ValidationInterface *validation_iface = nullptr;
|
||||
|
||||
Vulkan::BufferHandle upscaling_reference_rdram;
|
||||
Vulkan::BufferHandle upscaling_multisampled_rdram;
|
||||
Vulkan::BufferHandle upscaling_multisampled_hidden_rdram;
|
||||
|
||||
void validate_draw_state() const;
|
||||
|
||||
struct
|
||||
{
|
||||
uint8_t *host_rdram = nullptr;
|
||||
|
||||
Reference in New Issue
Block a user