mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-17 08:11:51 +00:00
rsx: Ignore or recover from unknown primitives
This also fixes a bug when recovering FIFO or creating such recovery point inside in_begin_end == true scope.
This commit is contained in:
parent
6a4ba9d562
commit
7260af032e
@ -2162,6 +2162,12 @@ namespace rsx
|
||||
fifo_ret_addr = saved_fifo_ret;
|
||||
std::this_thread::sleep_for(1ms);
|
||||
invalid_command_interrupt_raised = false;
|
||||
|
||||
if (std::exchange(in_begin_end, false) && !rsx::method_registers.current_draw_clause.empty())
|
||||
{
|
||||
execute_nop_draw();
|
||||
rsx::thread::end();
|
||||
}
|
||||
}
|
||||
|
||||
u32 thread::get_fifo_cmd()
|
||||
|
@ -21,19 +21,18 @@ rsx::primitive_type rsx::to_primitive_type(u8 in)
|
||||
{
|
||||
switch (in)
|
||||
{
|
||||
case 0: return rsx::primitive_type::invalid;
|
||||
case 1: return rsx::primitive_type::points;
|
||||
case 2: return rsx::primitive_type::lines;
|
||||
case 3: return rsx::primitive_type::line_loop;
|
||||
case 4: return rsx::primitive_type::line_strip;
|
||||
case 5: return rsx::primitive_type::triangles;
|
||||
case 6: return rsx::primitive_type::triangle_strip;
|
||||
case 7: return rsx::primitive_type::triangle_fan;
|
||||
case 8: return rsx::primitive_type::quads;
|
||||
case 9: return rsx::primitive_type::quad_strip;
|
||||
case 10: return rsx::primitive_type::polygon;
|
||||
case CELL_GCM_PRIMITIVE_POINTS: return rsx::primitive_type::points;
|
||||
case CELL_GCM_PRIMITIVE_LINES: return rsx::primitive_type::lines;
|
||||
case CELL_GCM_PRIMITIVE_LINE_LOOP: return rsx::primitive_type::line_loop;
|
||||
case CELL_GCM_PRIMITIVE_LINE_STRIP: return rsx::primitive_type::line_strip;
|
||||
case CELL_GCM_PRIMITIVE_TRIANGLES: return rsx::primitive_type::triangles;
|
||||
case CELL_GCM_PRIMITIVE_TRIANGLE_STRIP: return rsx::primitive_type::triangle_strip;
|
||||
case CELL_GCM_PRIMITIVE_TRIANGLE_FAN: return rsx::primitive_type::triangle_fan;
|
||||
case CELL_GCM_PRIMITIVE_QUADS: return rsx::primitive_type::quads;
|
||||
case CELL_GCM_PRIMITIVE_QUAD_STRIP: return rsx::primitive_type::quad_strip;
|
||||
case CELL_GCM_PRIMITIVE_POLYGON: return rsx::primitive_type::polygon;
|
||||
default: return rsx::primitive_type::invalid;
|
||||
}
|
||||
fmt::throw_exception("Unknown primitive type %d" HERE, in);
|
||||
}
|
||||
|
||||
enum
|
||||
|
@ -449,8 +449,22 @@ enum
|
||||
enum
|
||||
{
|
||||
// Index Array Type
|
||||
CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32 = 0,
|
||||
CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16 = 1,
|
||||
CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32 = 0,
|
||||
CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16 = 1,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CELL_GCM_PRIMITIVE_POINTS = 1,
|
||||
CELL_GCM_PRIMITIVE_LINES = 2,
|
||||
CELL_GCM_PRIMITIVE_LINE_LOOP = 3,
|
||||
CELL_GCM_PRIMITIVE_LINE_STRIP = 4,
|
||||
CELL_GCM_PRIMITIVE_TRIANGLES = 5,
|
||||
CELL_GCM_PRIMITIVE_TRIANGLE_STRIP= 6,
|
||||
CELL_GCM_PRIMITIVE_TRIANGLE_FAN = 7,
|
||||
CELL_GCM_PRIMITIVE_QUADS = 8,
|
||||
CELL_GCM_PRIMITIVE_QUAD_STRIP = 9,
|
||||
CELL_GCM_PRIMITIVE_POLYGON = 10,
|
||||
};
|
||||
|
||||
// GCM Texture
|
||||
|
@ -70,7 +70,7 @@ namespace rsx
|
||||
|
||||
void semaphore_acquire(thread* rsx, u32 /*_reg*/, u32 arg)
|
||||
{
|
||||
rsx->sync_point_request = true;
|
||||
if (!rsx->in_begin_end) rsx->sync_point_request = true;
|
||||
const u32 addr = get_address(method_registers.semaphore_offset_406e(), method_registers.semaphore_context_dma_406e());
|
||||
|
||||
const auto& sema = vm::_ref<atomic_be_t<u32>>(addr);
|
||||
@ -125,8 +125,8 @@ namespace rsx
|
||||
|
||||
// By avoiding doing this on flip's semaphore release
|
||||
// We allow last gcm's registers reset to occur in case of a crash
|
||||
const bool is_flip_sema = (offset == 0x10 && ctxt == CELL_GCM_CONTEXT_DMA_SEMAPHORE_R);
|
||||
if (!is_flip_sema)
|
||||
if (const bool is_flip_sema = (offset == 0x10 && ctxt == CELL_GCM_CONTEXT_DMA_SEMAPHORE_R);
|
||||
!is_flip_sema && !rsx->in_begin_end)
|
||||
{
|
||||
rsx->sync_point_request = true;
|
||||
}
|
||||
@ -464,9 +464,19 @@ namespace rsx
|
||||
|
||||
void set_begin_end(thread* rsxthr, u32 _reg, u32 arg)
|
||||
{
|
||||
if (arg)
|
||||
// Ignore upper bits
|
||||
if (const u8 prim = static_cast<u8>(arg))
|
||||
{
|
||||
rsx::method_registers.current_draw_clause.reset(to_primitive_type(arg));
|
||||
rsx::method_registers.current_draw_clause.reset(to_primitive_type(prim));
|
||||
|
||||
if (rsx::method_registers.current_draw_clause.primitive == rsx::primitive_type::invalid)
|
||||
{
|
||||
rsxthr->in_begin_end = true;
|
||||
|
||||
LOG_WARNING(RSX, "Invalid NV4097_SET_BEGIN_END value: 0x%x", arg);
|
||||
return;
|
||||
}
|
||||
|
||||
rsxthr->begin();
|
||||
return;
|
||||
}
|
||||
@ -496,6 +506,15 @@ namespace rsx
|
||||
|
||||
if (!rsx::method_registers.current_draw_clause.empty())
|
||||
{
|
||||
if (rsx::method_registers.current_draw_clause.primitive == rsx::primitive_type::invalid)
|
||||
{
|
||||
// Recover from invalid primitive only if draw clause is not empty
|
||||
rsxthr->invalid_command_interrupt_raised = true;
|
||||
|
||||
LOG_ERROR(RSX, "NV4097_SET_BEGIN_END aborted due to invalid primitive!");
|
||||
return;
|
||||
}
|
||||
|
||||
rsx::method_registers.current_draw_clause.compile();
|
||||
rsxthr->end();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user