mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-22 22:05:38 +00:00
GPU: Implement line rendering
This commit is contained in:
parent
f2a3629016
commit
390639e795
|
@ -580,7 +580,8 @@ bool GPU::HandleRenderCommand()
|
||||||
// polyline goes until we hit the termination code
|
// polyline goes until we hit the termination code
|
||||||
num_vertices = 0;
|
num_vertices = 0;
|
||||||
bool found_terminator = false;
|
bool found_terminator = false;
|
||||||
for (size_t pos = 0; pos < m_GP0_command.size(); pos += words_per_vertex)
|
for (u32 pos = BoolToUInt32(!rc.shading_enable); pos < static_cast<u32>(m_GP0_command.size());
|
||||||
|
pos += words_per_vertex)
|
||||||
{
|
{
|
||||||
if (m_GP0_command[pos] == 0x55555555)
|
if (m_GP0_command[pos] == 0x55555555)
|
||||||
{
|
{
|
||||||
|
|
|
@ -151,8 +151,8 @@ protected:
|
||||||
BitField<u32, u32, 0, 11> x_s11;
|
BitField<u32, u32, 0, 11> x_s11;
|
||||||
BitField<u32, u32, 16, 11> y_s11;
|
BitField<u32, u32, 16, 11> y_s11;
|
||||||
|
|
||||||
u32 x() const { return S11ToS32(x_s11); }
|
s32 x() const { return S11ToS32(x_s11); }
|
||||||
u32 y() const { return S11ToS32(y_s11); }
|
s32 y() const { return S11ToS32(y_s11); }
|
||||||
};
|
};
|
||||||
|
|
||||||
void SoftReset();
|
void SoftReset();
|
||||||
|
|
|
@ -111,6 +111,26 @@ void GPU_HW::LoadVertices(RenderCommand rc, u32 num_vertices)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Primitive::Line:
|
||||||
|
{
|
||||||
|
const u32 first_color = rc.color_for_first_vertex;
|
||||||
|
const bool shaded = rc.shading_enable;
|
||||||
|
|
||||||
|
u32 buffer_pos = 1;
|
||||||
|
for (u32 i = 0; i < num_vertices; i++)
|
||||||
|
{
|
||||||
|
// x/y are encoded differently for lines - 16 bits each
|
||||||
|
const u32 color = (shaded && i > 0) ? (m_GP0_command[buffer_pos++] & UINT32_C(0x00FFFFFF)) : first_color;
|
||||||
|
const s32 x = Truncate16(m_GP0_command[buffer_pos]);
|
||||||
|
const s32 y = Truncate16(m_GP0_command[buffer_pos++] >> 16);
|
||||||
|
m_batch.vertices.push_back(HWVertex{x, y, color});
|
||||||
|
}
|
||||||
|
|
||||||
|
FlushRender();
|
||||||
|
UpdateDisplay();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
UnreachableCode();
|
UnreachableCode();
|
||||||
break;
|
break;
|
||||||
|
@ -357,7 +377,7 @@ void main()
|
||||||
GPU_HW::HWRenderBatch::Primitive GPU_HW::GetPrimitiveForCommand(RenderCommand rc)
|
GPU_HW::HWRenderBatch::Primitive GPU_HW::GetPrimitiveForCommand(RenderCommand rc)
|
||||||
{
|
{
|
||||||
if (rc.primitive == Primitive::Line)
|
if (rc.primitive == Primitive::Line)
|
||||||
return HWRenderBatch::Primitive::Lines;
|
return rc.polyline ? HWRenderBatch::Primitive::LineStrip : HWRenderBatch::Primitive::Lines;
|
||||||
else if ((rc.primitive == Primitive::Polygon && rc.quad_polygon) || rc.primitive == Primitive::Rectangle)
|
else if ((rc.primitive == Primitive::Polygon && rc.quad_polygon) || rc.primitive == Primitive::Rectangle)
|
||||||
return HWRenderBatch::Primitive::TriangleStrip;
|
return HWRenderBatch::Primitive::TriangleStrip;
|
||||||
else
|
else
|
||||||
|
@ -395,9 +415,9 @@ void GPU_HW::DispatchRenderCommand(RenderCommand rc, u32 num_vertices)
|
||||||
}
|
}
|
||||||
|
|
||||||
// has any state changed which requires a new batch?
|
// has any state changed which requires a new batch?
|
||||||
const bool rc_transparency_enable = rc.transparency_enable;
|
const bool rc_transparency_enable = rc.IsTransparencyEnabled();
|
||||||
const bool rc_texture_enable = rc.texture_enable;
|
const bool rc_texture_enable = rc.IsTextureEnabled();
|
||||||
const bool rc_texture_blend_enable = !rc.texture_blend_disable;
|
const bool rc_texture_blend_enable = rc.IsTextureBlendingEnabled();
|
||||||
const HWRenderBatch::Primitive rc_primitive = GetPrimitiveForCommand(rc);
|
const HWRenderBatch::Primitive rc_primitive = GetPrimitiveForCommand(rc);
|
||||||
const u32 max_added_vertices = num_vertices + 2;
|
const u32 max_added_vertices = num_vertices + 2;
|
||||||
const bool buffer_overflow = (m_batch.vertices.size() + max_added_vertices) >= MAX_BATCH_VERTEX_COUNT;
|
const bool buffer_overflow = (m_batch.vertices.size() + max_added_vertices) >= MAX_BATCH_VERTEX_COUNT;
|
||||||
|
@ -405,9 +425,10 @@ void GPU_HW::DispatchRenderCommand(RenderCommand rc, u32 num_vertices)
|
||||||
m_batch.render_command_bits != rc.bits && m_batch.transparency_enable != rc_transparency_enable ||
|
m_batch.render_command_bits != rc.bits && m_batch.transparency_enable != rc_transparency_enable ||
|
||||||
m_batch.texture_enable != rc_texture_enable || m_batch.texture_blending_enable != rc_texture_blend_enable ||
|
m_batch.texture_enable != rc_texture_enable || m_batch.texture_blending_enable != rc_texture_blend_enable ||
|
||||||
m_batch.primitive != rc_primitive;
|
m_batch.primitive != rc_primitive;
|
||||||
|
const bool restart_line_strip = (rc_primitive == HWRenderBatch::Primitive::LineStrip);
|
||||||
const bool needs_flush =
|
const bool needs_flush =
|
||||||
!IsFlushed() && (m_render_state.IsTextureColorModeChanged() || m_render_state.IsTransparencyModeChanged() ||
|
!IsFlushed() && (m_render_state.IsTextureColorModeChanged() || m_render_state.IsTransparencyModeChanged() ||
|
||||||
buffer_overflow || rc_changed);
|
buffer_overflow || rc_changed || restart_line_strip);
|
||||||
if (needs_flush)
|
if (needs_flush)
|
||||||
FlushRender();
|
FlushRender();
|
||||||
|
|
||||||
|
|
|
@ -32,8 +32,9 @@ protected:
|
||||||
enum class Primitive : u8
|
enum class Primitive : u8
|
||||||
{
|
{
|
||||||
Lines = 0,
|
Lines = 0,
|
||||||
Triangles = 1,
|
LineStrip = 1,
|
||||||
TriangleStrip = 2
|
Triangles = 2,
|
||||||
|
TriangleStrip = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
u32 render_command_bits;
|
u32 render_command_bits;
|
||||||
|
|
|
@ -441,7 +441,7 @@ void GPU_HW_OpenGL::FlushRender()
|
||||||
glBufferSubData(GL_ARRAY_BUFFER, 0, static_cast<GLsizei>(sizeof(HWVertex) * m_batch.vertices.size()),
|
glBufferSubData(GL_ARRAY_BUFFER, 0, static_cast<GLsizei>(sizeof(HWVertex) * m_batch.vertices.size()),
|
||||||
m_batch.vertices.data());
|
m_batch.vertices.data());
|
||||||
|
|
||||||
static constexpr std::array<GLenum, 3> gl_primitives = {{GL_LINES, GL_TRIANGLES, GL_TRIANGLE_STRIP}};
|
static constexpr std::array<GLenum, 4> gl_primitives = {{GL_LINES, GL_LINE_STRIP, GL_TRIANGLES, GL_TRIANGLE_STRIP}};
|
||||||
glDrawArrays(gl_primitives[static_cast<u8>(m_batch.primitive)], 0, static_cast<GLsizei>(m_batch.vertices.size()));
|
glDrawArrays(gl_primitives[static_cast<u8>(m_batch.primitive)], 0, static_cast<GLsizei>(m_batch.vertices.size()));
|
||||||
|
|
||||||
m_batch.vertices.clear();
|
m_batch.vertices.clear();
|
||||||
|
|
Loading…
Reference in a new issue