Merge pull request #3491 from ReinUsesLisp/polygon-modes
gl_rasterizer: Implement polygon modes and fill rectangles
This commit is contained in:
commit
b30b1f741d
|
@ -524,6 +524,12 @@ public:
|
||||||
FractionalEven = 2,
|
FractionalEven = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class PolygonMode : u32 {
|
||||||
|
Point = 0x1b00,
|
||||||
|
Line = 0x1b01,
|
||||||
|
Fill = 0x1b02,
|
||||||
|
};
|
||||||
|
|
||||||
struct RenderTargetConfig {
|
struct RenderTargetConfig {
|
||||||
u32 address_high;
|
u32 address_high;
|
||||||
u32 address_low;
|
u32 address_low;
|
||||||
|
@ -705,7 +711,12 @@ public:
|
||||||
|
|
||||||
s32 clear_stencil;
|
s32 clear_stencil;
|
||||||
|
|
||||||
INSERT_UNION_PADDING_WORDS(0x7);
|
INSERT_UNION_PADDING_WORDS(0x2);
|
||||||
|
|
||||||
|
PolygonMode polygon_mode_front;
|
||||||
|
PolygonMode polygon_mode_back;
|
||||||
|
|
||||||
|
INSERT_UNION_PADDING_WORDS(0x3);
|
||||||
|
|
||||||
u32 polygon_offset_point_enable;
|
u32 polygon_offset_point_enable;
|
||||||
u32 polygon_offset_line_enable;
|
u32 polygon_offset_line_enable;
|
||||||
|
@ -764,7 +775,11 @@ public:
|
||||||
BitField<12, 4, u32> viewport;
|
BitField<12, 4, u32> viewport;
|
||||||
} clear_flags;
|
} clear_flags;
|
||||||
|
|
||||||
INSERT_UNION_PADDING_WORDS(0x19);
|
INSERT_UNION_PADDING_WORDS(0x10);
|
||||||
|
|
||||||
|
u32 fill_rectangle;
|
||||||
|
|
||||||
|
INSERT_UNION_PADDING_WORDS(0x8);
|
||||||
|
|
||||||
std::array<VertexAttribute, NumVertexAttributes> vertex_attrib_format;
|
std::array<VertexAttribute, NumVertexAttributes> vertex_attrib_format;
|
||||||
|
|
||||||
|
@ -1422,6 +1437,8 @@ ASSERT_REG_POSITION(depth_mode, 0x35F);
|
||||||
ASSERT_REG_POSITION(clear_color[0], 0x360);
|
ASSERT_REG_POSITION(clear_color[0], 0x360);
|
||||||
ASSERT_REG_POSITION(clear_depth, 0x364);
|
ASSERT_REG_POSITION(clear_depth, 0x364);
|
||||||
ASSERT_REG_POSITION(clear_stencil, 0x368);
|
ASSERT_REG_POSITION(clear_stencil, 0x368);
|
||||||
|
ASSERT_REG_POSITION(polygon_mode_front, 0x36B);
|
||||||
|
ASSERT_REG_POSITION(polygon_mode_back, 0x36C);
|
||||||
ASSERT_REG_POSITION(polygon_offset_point_enable, 0x370);
|
ASSERT_REG_POSITION(polygon_offset_point_enable, 0x370);
|
||||||
ASSERT_REG_POSITION(polygon_offset_line_enable, 0x371);
|
ASSERT_REG_POSITION(polygon_offset_line_enable, 0x371);
|
||||||
ASSERT_REG_POSITION(polygon_offset_fill_enable, 0x372);
|
ASSERT_REG_POSITION(polygon_offset_fill_enable, 0x372);
|
||||||
|
@ -1435,6 +1452,7 @@ ASSERT_REG_POSITION(rt_separate_frag_data, 0x3EB);
|
||||||
ASSERT_REG_POSITION(depth_bounds, 0x3E7);
|
ASSERT_REG_POSITION(depth_bounds, 0x3E7);
|
||||||
ASSERT_REG_POSITION(zeta, 0x3F8);
|
ASSERT_REG_POSITION(zeta, 0x3F8);
|
||||||
ASSERT_REG_POSITION(clear_flags, 0x43E);
|
ASSERT_REG_POSITION(clear_flags, 0x43E);
|
||||||
|
ASSERT_REG_POSITION(fill_rectangle, 0x44F);
|
||||||
ASSERT_REG_POSITION(vertex_attrib_format, 0x458);
|
ASSERT_REG_POSITION(vertex_attrib_format, 0x458);
|
||||||
ASSERT_REG_POSITION(rt_control, 0x487);
|
ASSERT_REG_POSITION(rt_control, 0x487);
|
||||||
ASSERT_REG_POSITION(zeta_width, 0x48a);
|
ASSERT_REG_POSITION(zeta_width, 0x48a);
|
||||||
|
|
|
@ -487,6 +487,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
|
||||||
|
|
||||||
SyncViewport();
|
SyncViewport();
|
||||||
SyncRasterizeEnable();
|
SyncRasterizeEnable();
|
||||||
|
SyncPolygonModes();
|
||||||
SyncColorMask();
|
SyncColorMask();
|
||||||
SyncFragmentColorClampState();
|
SyncFragmentColorClampState();
|
||||||
SyncMultiSampleState();
|
SyncMultiSampleState();
|
||||||
|
@ -1096,6 +1097,45 @@ void RasterizerOpenGL::SyncRasterizeEnable() {
|
||||||
oglEnable(GL_RASTERIZER_DISCARD, gpu.regs.rasterize_enable == 0);
|
oglEnable(GL_RASTERIZER_DISCARD, gpu.regs.rasterize_enable == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RasterizerOpenGL::SyncPolygonModes() {
|
||||||
|
auto& gpu = system.GPU().Maxwell3D();
|
||||||
|
auto& flags = gpu.dirty.flags;
|
||||||
|
if (!flags[Dirty::PolygonModes]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
flags[Dirty::PolygonModes] = false;
|
||||||
|
|
||||||
|
if (gpu.regs.fill_rectangle) {
|
||||||
|
if (!GLAD_GL_NV_fill_rectangle) {
|
||||||
|
LOG_ERROR(Render_OpenGL, "GL_NV_fill_rectangle used and not supported");
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
flags[Dirty::PolygonModeFront] = true;
|
||||||
|
flags[Dirty::PolygonModeBack] = true;
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL_RECTANGLE_NV);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gpu.regs.polygon_mode_front == gpu.regs.polygon_mode_back) {
|
||||||
|
flags[Dirty::PolygonModeFront] = false;
|
||||||
|
flags[Dirty::PolygonModeBack] = false;
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK, MaxwellToGL::PolygonMode(gpu.regs.polygon_mode_front));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags[Dirty::PolygonModeFront]) {
|
||||||
|
flags[Dirty::PolygonModeFront] = false;
|
||||||
|
glPolygonMode(GL_FRONT, MaxwellToGL::PolygonMode(gpu.regs.polygon_mode_front));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags[Dirty::PolygonModeBack]) {
|
||||||
|
flags[Dirty::PolygonModeBack] = false;
|
||||||
|
glPolygonMode(GL_BACK, MaxwellToGL::PolygonMode(gpu.regs.polygon_mode_back));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void RasterizerOpenGL::SyncColorMask() {
|
void RasterizerOpenGL::SyncColorMask() {
|
||||||
auto& gpu = system.GPU().Maxwell3D();
|
auto& gpu = system.GPU().Maxwell3D();
|
||||||
auto& flags = gpu.dirty.flags;
|
auto& flags = gpu.dirty.flags;
|
||||||
|
|
|
@ -178,6 +178,9 @@ private:
|
||||||
/// Syncs the rasterizer enable state to match the guest state
|
/// Syncs the rasterizer enable state to match the guest state
|
||||||
void SyncRasterizeEnable();
|
void SyncRasterizeEnable();
|
||||||
|
|
||||||
|
/// Syncs polygon modes to match the guest state
|
||||||
|
void SyncPolygonModes();
|
||||||
|
|
||||||
/// Syncs Color Mask
|
/// Syncs Color Mask
|
||||||
void SyncColorMask();
|
void SyncColorMask();
|
||||||
|
|
||||||
|
|
|
@ -94,6 +94,15 @@ void SetupDirtyShaders(Tables& tables) {
|
||||||
Shaders);
|
Shaders);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetupDirtyPolygonModes(Tables& tables) {
|
||||||
|
tables[0][OFF(polygon_mode_front)] = PolygonModeFront;
|
||||||
|
tables[0][OFF(polygon_mode_back)] = PolygonModeBack;
|
||||||
|
|
||||||
|
tables[1][OFF(polygon_mode_front)] = PolygonModes;
|
||||||
|
tables[1][OFF(polygon_mode_back)] = PolygonModes;
|
||||||
|
tables[0][OFF(fill_rectangle)] = PolygonModes;
|
||||||
|
}
|
||||||
|
|
||||||
void SetupDirtyDepthTest(Tables& tables) {
|
void SetupDirtyDepthTest(Tables& tables) {
|
||||||
auto& table = tables[0];
|
auto& table = tables[0];
|
||||||
table[OFF(depth_test_enable)] = DepthTest;
|
table[OFF(depth_test_enable)] = DepthTest;
|
||||||
|
@ -211,6 +220,7 @@ void StateTracker::Initialize() {
|
||||||
SetupDirtyVertexArrays(tables);
|
SetupDirtyVertexArrays(tables);
|
||||||
SetupDirtyVertexFormat(tables);
|
SetupDirtyVertexFormat(tables);
|
||||||
SetupDirtyShaders(tables);
|
SetupDirtyShaders(tables);
|
||||||
|
SetupDirtyPolygonModes(tables);
|
||||||
SetupDirtyDepthTest(tables);
|
SetupDirtyDepthTest(tables);
|
||||||
SetupDirtyStencilTest(tables);
|
SetupDirtyStencilTest(tables);
|
||||||
SetupDirtyAlphaTest(tables);
|
SetupDirtyAlphaTest(tables);
|
||||||
|
|
|
@ -59,6 +59,10 @@ enum : u8 {
|
||||||
Shaders,
|
Shaders,
|
||||||
ClipDistances,
|
ClipDistances,
|
||||||
|
|
||||||
|
PolygonModes,
|
||||||
|
PolygonModeFront,
|
||||||
|
PolygonModeBack,
|
||||||
|
|
||||||
ColorMask,
|
ColorMask,
|
||||||
FrontFace,
|
FrontFace,
|
||||||
CullTest,
|
CullTest,
|
||||||
|
@ -111,6 +115,13 @@ public:
|
||||||
flags[OpenGL::Dirty::VertexInstance0 + 1] = true;
|
flags[OpenGL::Dirty::VertexInstance0 + 1] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NotifyPolygonModes() {
|
||||||
|
auto& flags = system.GPU().Maxwell3D().dirty.flags;
|
||||||
|
flags[OpenGL::Dirty::PolygonModes] = true;
|
||||||
|
flags[OpenGL::Dirty::PolygonModeFront] = true;
|
||||||
|
flags[OpenGL::Dirty::PolygonModeBack] = true;
|
||||||
|
}
|
||||||
|
|
||||||
void NotifyViewport0() {
|
void NotifyViewport0() {
|
||||||
auto& flags = system.GPU().Maxwell3D().dirty.flags;
|
auto& flags = system.GPU().Maxwell3D().dirty.flags;
|
||||||
flags[OpenGL::Dirty::Viewports] = true;
|
flags[OpenGL::Dirty::Viewports] = true;
|
||||||
|
|
|
@ -488,5 +488,18 @@ inline GLenum LogicOp(Maxwell::LogicOperation operation) {
|
||||||
return GL_COPY;
|
return GL_COPY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline GLenum PolygonMode(Maxwell::PolygonMode polygon_mode) {
|
||||||
|
switch (polygon_mode) {
|
||||||
|
case Maxwell::PolygonMode::Point:
|
||||||
|
return GL_POINT;
|
||||||
|
case Maxwell::PolygonMode::Line:
|
||||||
|
return GL_LINE;
|
||||||
|
case Maxwell::PolygonMode::Fill:
|
||||||
|
return GL_FILL;
|
||||||
|
}
|
||||||
|
UNREACHABLE_MSG("Invalid polygon mode={}", static_cast<int>(polygon_mode));
|
||||||
|
return GL_FILL;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace MaxwellToGL
|
} // namespace MaxwellToGL
|
||||||
} // namespace OpenGL
|
} // namespace OpenGL
|
||||||
|
|
|
@ -576,6 +576,7 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
|
||||||
|
|
||||||
// TODO: Signal state tracker about these changes
|
// TODO: Signal state tracker about these changes
|
||||||
state_tracker.NotifyScreenDrawVertexArray();
|
state_tracker.NotifyScreenDrawVertexArray();
|
||||||
|
state_tracker.NotifyPolygonModes();
|
||||||
state_tracker.NotifyViewport0();
|
state_tracker.NotifyViewport0();
|
||||||
state_tracker.NotifyScissor0();
|
state_tracker.NotifyScissor0();
|
||||||
state_tracker.NotifyColorMask0();
|
state_tracker.NotifyColorMask0();
|
||||||
|
@ -611,6 +612,7 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
|
||||||
glDisable(GL_ALPHA_TEST);
|
glDisable(GL_ALPHA_TEST);
|
||||||
glDisablei(GL_BLEND, 0);
|
glDisablei(GL_BLEND, 0);
|
||||||
glDisablei(GL_SCISSOR_TEST, 0);
|
glDisablei(GL_SCISSOR_TEST, 0);
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
glCullFace(GL_BACK);
|
glCullFace(GL_BACK);
|
||||||
glFrontFace(GL_CW);
|
glFrontFace(GL_CW);
|
||||||
glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||||
|
|
Loading…
Reference in New Issue