diff --git a/rpcs3/Emu/RSX/NV47/HW/nv308a.cpp b/rpcs3/Emu/RSX/NV47/HW/nv308a.cpp index be3fab8830..163ddb9a4c 100644 --- a/rpcs3/Emu/RSX/NV47/HW/nv308a.cpp +++ b/rpcs3/Emu/RSX/NV47/HW/nv308a.cpp @@ -35,6 +35,13 @@ namespace rsx u32 count = std::min({ fifo_args_cnt, fifo_read_limit, method_range }); + if (!count) + { + rsx_log.error("nv308a::color - No data to read/write."); + RSX(ctx)->fifo_ctrl->skip_methods(fifo_args_cnt - 1); + return; + } + const u32 dst_dma = REGS(ctx)->blit_engine_output_location_nv3062(); const u32 dst_offset = REGS(ctx)->blit_engine_output_offset_nv3062(); const u32 out_pitch = REGS(ctx)->blit_engine_output_pitch_nv3062(); diff --git a/rpcs3/Emu/RSX/NV47/HW/nv4097.cpp b/rpcs3/Emu/RSX/NV47/HW/nv4097.cpp index 78f01f4059..eeb52a2242 100644 --- a/rpcs3/Emu/RSX/NV47/HW/nv4097.cpp +++ b/rpcs3/Emu/RSX/NV47/HW/nv4097.cpp @@ -82,6 +82,14 @@ namespace rsx rcount = 0; } + if (rcount == 0) + { + // Out-of-bounds write is a NOP + rsx_log.trace("Out of bounds write for transform constant block."); + RSX(ctx)->fifo_ctrl->skip_methods(fifo_args_cnt - 1); + return; + } + if (RSX(ctx)->in_begin_end && !REGS(ctx)->current_draw_clause.empty()) { // Updating constants mid-draw is messy. Defer the writes @@ -148,6 +156,14 @@ namespace rsx rcount -= max - (max_vertex_program_instructions * 4); } + if (!rcount) + { + // Out-of-bounds write is a NOP + rsx_log.trace("Out of bounds write for transform program block."); + RSX(ctx)->fifo_ctrl->skip_methods(fifo_args_cnt - 1); + return; + } + const auto fifo_span = RSX(ctx)->fifo_ctrl->get_current_arg_ptr(rcount); if (fifo_span.size() < rcount) diff --git a/rpcs3/Emu/RSX/RSXFIFO.cpp b/rpcs3/Emu/RSX/RSXFIFO.cpp index 7982da2393..28cd0c286d 100644 --- a/rpcs3/Emu/RSX/RSXFIFO.cpp +++ b/rpcs3/Emu/RSX/RSXFIFO.cpp @@ -225,6 +225,13 @@ namespace rsx std::span FIFO_control::get_current_arg_ptr(u32 length_in_words) const { + if (!length_in_words) + { + // This means the caller is doing something stupid + rsx_log.error("Invalid access to FIFO args data, requested length = 0"); + return {}; + } + if (g_cfg.core.rsx_fifo_accuracy) { // Return a pointer to the cache storage with confined access