mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-12-06 07:12:28 +01:00
gl: Implement polygon render modes
This commit is contained in:
parent
3df0c8caef
commit
bcdf2ef36f
|
|
@ -7,36 +7,14 @@
|
|||
|
||||
namespace gl
|
||||
{
|
||||
GLenum comparison_op(rsx::comparison_function op)
|
||||
inline GLenum comparison_op(rsx::comparison_function op)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case rsx::comparison_function::never: return GL_NEVER;
|
||||
case rsx::comparison_function::less: return GL_LESS;
|
||||
case rsx::comparison_function::equal: return GL_EQUAL;
|
||||
case rsx::comparison_function::less_or_equal: return GL_LEQUAL;
|
||||
case rsx::comparison_function::greater: return GL_GREATER;
|
||||
case rsx::comparison_function::not_equal: return GL_NOTEQUAL;
|
||||
case rsx::comparison_function::greater_or_equal: return GL_GEQUAL;
|
||||
case rsx::comparison_function::always: return GL_ALWAYS;
|
||||
}
|
||||
fmt::throw_exception("Unsupported comparison op 0x%X", static_cast<u32>(op));
|
||||
return static_cast<GLenum>(op);
|
||||
}
|
||||
|
||||
GLenum stencil_op(rsx::stencil_op op)
|
||||
inline GLenum stencil_op(rsx::stencil_op op)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case rsx::stencil_op::invert: return GL_INVERT;
|
||||
case rsx::stencil_op::keep: return GL_KEEP;
|
||||
case rsx::stencil_op::zero: return GL_ZERO;
|
||||
case rsx::stencil_op::replace: return GL_REPLACE;
|
||||
case rsx::stencil_op::incr: return GL_INCR;
|
||||
case rsx::stencil_op::decr: return GL_DECR;
|
||||
case rsx::stencil_op::incr_wrap: return GL_INCR_WRAP;
|
||||
case rsx::stencil_op::decr_wrap: return GL_DECR_WRAP;
|
||||
}
|
||||
fmt::throw_exception("Unsupported stencil op 0x%X", static_cast<u32>(op));
|
||||
return static_cast<GLenum>(op);
|
||||
}
|
||||
|
||||
GLenum blend_equation(rsx::blend_equation op)
|
||||
|
|
@ -62,76 +40,33 @@ namespace gl
|
|||
}
|
||||
}
|
||||
|
||||
GLenum blend_factor(rsx::blend_factor op)
|
||||
inline GLenum blend_factor(rsx::blend_factor op)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case rsx::blend_factor::zero: return GL_ZERO;
|
||||
case rsx::blend_factor::one: return GL_ONE;
|
||||
case rsx::blend_factor::src_color: return GL_SRC_COLOR;
|
||||
case rsx::blend_factor::one_minus_src_color: return GL_ONE_MINUS_SRC_COLOR;
|
||||
case rsx::blend_factor::dst_color: return GL_DST_COLOR;
|
||||
case rsx::blend_factor::one_minus_dst_color: return GL_ONE_MINUS_DST_COLOR;
|
||||
case rsx::blend_factor::src_alpha: return GL_SRC_ALPHA;
|
||||
case rsx::blend_factor::one_minus_src_alpha: return GL_ONE_MINUS_SRC_ALPHA;
|
||||
case rsx::blend_factor::dst_alpha: return GL_DST_ALPHA;
|
||||
case rsx::blend_factor::one_minus_dst_alpha: return GL_ONE_MINUS_DST_ALPHA;
|
||||
case rsx::blend_factor::src_alpha_saturate: return GL_SRC_ALPHA_SATURATE;
|
||||
case rsx::blend_factor::constant_color: return GL_CONSTANT_COLOR;
|
||||
case rsx::blend_factor::one_minus_constant_color: return GL_ONE_MINUS_CONSTANT_COLOR;
|
||||
case rsx::blend_factor::constant_alpha: return GL_CONSTANT_ALPHA;
|
||||
case rsx::blend_factor::one_minus_constant_alpha: return GL_ONE_MINUS_CONSTANT_ALPHA;
|
||||
}
|
||||
fmt::throw_exception("Unsupported blend factor 0x%X", static_cast<u32>(op));
|
||||
return static_cast<GLenum>(op);
|
||||
}
|
||||
|
||||
GLenum logic_op(rsx::logic_op op)
|
||||
inline GLenum logic_op(rsx::logic_op op)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case rsx::logic_op::logic_clear: return GL_CLEAR;
|
||||
case rsx::logic_op::logic_and: return GL_AND;
|
||||
case rsx::logic_op::logic_and_reverse: return GL_AND_REVERSE;
|
||||
case rsx::logic_op::logic_copy: return GL_COPY;
|
||||
case rsx::logic_op::logic_and_inverted: return GL_AND_INVERTED;
|
||||
case rsx::logic_op::logic_noop: return GL_NOOP;
|
||||
case rsx::logic_op::logic_xor: return GL_XOR;
|
||||
case rsx::logic_op::logic_or: return GL_OR;
|
||||
case rsx::logic_op::logic_nor: return GL_NOR;
|
||||
case rsx::logic_op::logic_equiv: return GL_EQUIV;
|
||||
case rsx::logic_op::logic_invert: return GL_INVERT;
|
||||
case rsx::logic_op::logic_or_reverse: return GL_OR_REVERSE;
|
||||
case rsx::logic_op::logic_copy_inverted: return GL_COPY_INVERTED;
|
||||
case rsx::logic_op::logic_or_inverted: return GL_OR_INVERTED;
|
||||
case rsx::logic_op::logic_nand: return GL_NAND;
|
||||
case rsx::logic_op::logic_set: return GL_SET;
|
||||
}
|
||||
fmt::throw_exception("Unsupported logic op 0x%X", static_cast<u32>(op));
|
||||
return static_cast<GLenum>(op);
|
||||
}
|
||||
|
||||
GLenum front_face(rsx::front_face op)
|
||||
inline GLenum front_face(rsx::front_face op)
|
||||
{
|
||||
// NOTE: RSX face winding is always based off of upper-left corner like vulkan, but GL is bottom left
|
||||
// shader_window_origin register does not affect this
|
||||
// verified with Outrun Online Arcade (window_origin::top) and DS2 (window_origin::bottom)
|
||||
// correctness of face winding checked using stencil test (GOW collection shadows)
|
||||
switch (op)
|
||||
{
|
||||
case rsx::front_face::cw: return GL_CCW;
|
||||
case rsx::front_face::ccw: return GL_CW;
|
||||
}
|
||||
fmt::throw_exception("Unsupported front face 0x%X", static_cast<u32>(op));
|
||||
return static_cast<GLenum>(op) ^ 1u;
|
||||
}
|
||||
|
||||
GLenum cull_face(rsx::cull_face op)
|
||||
inline GLenum cull_face(rsx::cull_face op)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case rsx::cull_face::front: return GL_FRONT;
|
||||
case rsx::cull_face::back: return GL_BACK;
|
||||
case rsx::cull_face::front_and_back: return GL_FRONT_AND_BACK;
|
||||
return static_cast<GLenum>(op);
|
||||
}
|
||||
fmt::throw_exception("Unsupported cull face 0x%X", static_cast<u32>(op));
|
||||
|
||||
inline GLenum polygon_mode(rsx::polygon_mode mode)
|
||||
{
|
||||
return static_cast<GLenum>(mode);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -335,6 +270,10 @@ void GLGSRender::update_draw_state()
|
|||
// Clip planes
|
||||
gl_state.clip_planes((current_vertex_program.output_mask >> CELL_GCM_ATTRIB_OUTPUT_UC0) & 0x3F);
|
||||
|
||||
// Polygon mode. We can only have one polygon mode active at one time, so we need to determine if any face is currently culled.
|
||||
const bool show_back = REGS(m_ctx)->cull_face_enabled() && REGS(m_ctx)->cull_face_mode() == rsx::cull_face::front;
|
||||
gl_state.polygon_mode(gl::polygon_mode(show_back ? REGS(m_ctx)->polygon_mode_back() : REGS(m_ctx)->polygon_mode_front()));
|
||||
|
||||
//TODO
|
||||
//NV4097_SET_ANISO_SPREAD
|
||||
//NV4097_SET_SPECULAR_ENABLE
|
||||
|
|
@ -342,9 +281,6 @@ void GLGSRender::update_draw_state()
|
|||
//NV4097_SET_FLAT_SHADE_OP
|
||||
//NV4097_SET_EDGE_FLAG
|
||||
//NV4097_SET_COLOR_KEY_COLOR
|
||||
//NV4097_SET_SHADER_CONTROL
|
||||
//NV4097_SET_ZMIN_MAX_CONTROL
|
||||
//NV4097_SET_ANTI_ALIASING_CONTROL
|
||||
//NV4097_SET_CLIP_ID_TEST_ENABLE
|
||||
|
||||
// For OGL Z range is updated every draw as it is separate from viewport config
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ namespace gl
|
|||
const u32 STENCIL_FRONT_OP = 0xFFFF0007;
|
||||
const u32 STENCIL_BACK_OP = 0xFFFF0008;
|
||||
const u32 STENCIL_BACK_MASK = 0xFFFF0009;
|
||||
const u32 POLYGON_MODE = 0xFFFF000A;
|
||||
|
||||
std::unordered_map<GLenum, u64> properties = {};
|
||||
std::unordered_map<GLenum, std::array<u64, 4>> indexed_properties = {};
|
||||
|
|
@ -353,6 +354,15 @@ namespace gl
|
|||
}
|
||||
}
|
||||
|
||||
void polygon_mode(GLenum mode)
|
||||
{
|
||||
if (!test_and_set_property(POLYGON_MODE, mode))
|
||||
{
|
||||
// Note: GL4+ does not support separate polygon mode per-face-type
|
||||
glPolygonMode(GL_FRONT_AND_BACK, mode);
|
||||
}
|
||||
}
|
||||
|
||||
void use_program(GLuint program)
|
||||
{
|
||||
if (current_program == program)
|
||||
|
|
|
|||
|
|
@ -1321,6 +1321,16 @@ namespace rsx
|
|||
{
|
||||
return decode<NV4097_SET_POLYGON_STIPPLE>().enabled();
|
||||
}
|
||||
|
||||
polygon_mode polygon_mode_front() const
|
||||
{
|
||||
return decode<NV4097_SET_FRONT_POLYGON_MODE>().front_polygon_mode();
|
||||
}
|
||||
|
||||
polygon_mode polygon_mode_back() const
|
||||
{
|
||||
return decode<NV4097_SET_BACK_POLYGON_MODE>().back_polygon_mode();
|
||||
}
|
||||
};
|
||||
|
||||
extern rsx_state method_registers;
|
||||
|
|
|
|||
Loading…
Reference in a new issue