GPU/HW: Fix potential crash in rectangle expansion
This commit is contained in:
parent
a298e93004
commit
0690491883
|
@ -88,6 +88,7 @@ void GPU_HW::LoadVertices(RenderCommand rc, u32 num_vertices, const u32* command
|
||||||
case Primitive::Polygon:
|
case Primitive::Polygon:
|
||||||
{
|
{
|
||||||
DebugAssert(num_vertices == 3 || num_vertices == 4);
|
DebugAssert(num_vertices == 3 || num_vertices == 4);
|
||||||
|
EnsureVertexBufferSpace(rc.quad_polygon ? 6 : 3);
|
||||||
|
|
||||||
const u32 first_color = rc.color_for_first_vertex;
|
const u32 first_color = rc.color_for_first_vertex;
|
||||||
const bool shaded = rc.shading_enable;
|
const bool shaded = rc.shading_enable;
|
||||||
|
@ -201,6 +202,11 @@ void GPU_HW::LoadVertices(RenderCommand rc, u32 num_vertices, const u32* command
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// we can split the rectangle up into potentially 8 quads
|
||||||
|
const u32 required_vertices = 6 * ((rectangle_width + (TEXTURE_PAGE_WIDTH - 1)) / TEXTURE_PAGE_WIDTH) *
|
||||||
|
((rectangle_height + (TEXTURE_PAGE_HEIGHT - 1)) / TEXTURE_PAGE_HEIGHT);
|
||||||
|
EnsureVertexBufferSpace(required_vertices);
|
||||||
|
|
||||||
min_x = pos_x;
|
min_x = pos_x;
|
||||||
min_y = pos_y;
|
min_y = pos_y;
|
||||||
max_x = pos_x + rectangle_width;
|
max_x = pos_x + rectangle_width;
|
||||||
|
@ -243,6 +249,8 @@ void GPU_HW::LoadVertices(RenderCommand rc, u32 num_vertices, const u32* command
|
||||||
|
|
||||||
case Primitive::Line:
|
case Primitive::Line:
|
||||||
{
|
{
|
||||||
|
EnsureVertexBufferSpace(num_vertices * 2);
|
||||||
|
|
||||||
const u32 first_color = rc.color_for_first_vertex;
|
const u32 first_color = rc.color_for_first_vertex;
|
||||||
const bool shaded = rc.shading_enable;
|
const bool shaded = rc.shading_enable;
|
||||||
|
|
||||||
|
@ -348,6 +356,19 @@ void GPU_HW::IncludeVRAMDityRectangle(const Common::Rectangle<u32>& rect)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GPU_HW::EnsureVertexBufferSpace(u32 required_vertices)
|
||||||
|
{
|
||||||
|
if (m_batch_current_vertex_ptr)
|
||||||
|
{
|
||||||
|
if (GetBatchVertexSpace() >= required_vertices)
|
||||||
|
return;
|
||||||
|
|
||||||
|
FlushRender();
|
||||||
|
}
|
||||||
|
|
||||||
|
MapBatchVertexPointer(required_vertices);
|
||||||
|
}
|
||||||
|
|
||||||
void GPU_HW::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color)
|
void GPU_HW::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color)
|
||||||
{
|
{
|
||||||
IncludeVRAMDityRectangle(
|
IncludeVRAMDityRectangle(
|
||||||
|
@ -406,11 +427,9 @@ void GPU_HW::DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32
|
||||||
rc.transparency_enable ? m_draw_mode.GetTransparencyMode() : TransparencyMode::Disabled;
|
rc.transparency_enable ? m_draw_mode.GetTransparencyMode() : TransparencyMode::Disabled;
|
||||||
const BatchPrimitive rc_primitive = GetPrimitiveForCommand(rc);
|
const BatchPrimitive rc_primitive = GetPrimitiveForCommand(rc);
|
||||||
const bool dithering_enable = (!m_true_color && rc.IsDitheringEnabled()) ? m_GPUSTAT.dither_enable : false;
|
const bool dithering_enable = (!m_true_color && rc.IsDitheringEnabled()) ? m_GPUSTAT.dither_enable : false;
|
||||||
const u32 max_added_vertices = num_vertices + 5;
|
|
||||||
if (!IsFlushed())
|
if (!IsFlushed())
|
||||||
{
|
{
|
||||||
const bool buffer_overflow = GetBatchVertexSpace() < max_added_vertices;
|
if (m_batch.texture_mode != texture_mode || m_batch.transparency_mode != transparency_mode ||
|
||||||
if (buffer_overflow || m_batch.texture_mode != texture_mode || m_batch.transparency_mode != transparency_mode ||
|
|
||||||
m_batch.primitive != rc_primitive || dithering_enable != m_batch.dithering || m_drawing_area_changed ||
|
m_batch.primitive != rc_primitive || dithering_enable != m_batch.dithering || m_drawing_area_changed ||
|
||||||
m_drawing_offset_changed || m_draw_mode.IsTextureWindowChanged())
|
m_drawing_offset_changed || m_draw_mode.IsTextureWindowChanged())
|
||||||
{
|
{
|
||||||
|
@ -444,10 +463,6 @@ void GPU_HW::DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32
|
||||||
m_batch_ubo_dirty = true;
|
m_batch_ubo_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// map buffer if it's not already done
|
|
||||||
if (!m_batch_current_vertex_ptr)
|
|
||||||
MapBatchVertexPointer(max_added_vertices);
|
|
||||||
|
|
||||||
// update state
|
// update state
|
||||||
m_batch.primitive = rc_primitive;
|
m_batch.primitive = rc_primitive;
|
||||||
m_batch.texture_mode = texture_mode;
|
m_batch.texture_mode = texture_mode;
|
||||||
|
|
|
@ -132,6 +132,7 @@ protected:
|
||||||
|
|
||||||
u32 GetBatchVertexSpace() const { return static_cast<u32>(m_batch_end_vertex_ptr - m_batch_current_vertex_ptr); }
|
u32 GetBatchVertexSpace() const { return static_cast<u32>(m_batch_end_vertex_ptr - m_batch_current_vertex_ptr); }
|
||||||
u32 GetBatchVertexCount() const { return static_cast<u32>(m_batch_current_vertex_ptr - m_batch_start_vertex_ptr); }
|
u32 GetBatchVertexCount() const { return static_cast<u32>(m_batch_current_vertex_ptr - m_batch_start_vertex_ptr); }
|
||||||
|
void EnsureVertexBufferSpace(u32 required_vertices);
|
||||||
|
|
||||||
bool IsFlushed() const { return m_batch_current_vertex_ptr == m_batch_start_vertex_ptr; }
|
bool IsFlushed() const { return m_batch_current_vertex_ptr == m_batch_start_vertex_ptr; }
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue