Implement depth clamp

This commit is contained in:
Rodolfo Bogado 2018-11-23 12:11:21 -03:00
parent 1856d0ee8a
commit dfdbfa69e5
5 changed files with 58 additions and 10 deletions

View file

@ -902,8 +902,15 @@ public:
u32 viewport_transform_enabled; u32 viewport_transform_enabled;
INSERT_PADDING_WORDS(0x25); INSERT_PADDING_WORDS(0x3);
union {
BitField<0, 1, u32> depth_range_0_1;
BitField<3, 1, u32> depth_clamp_near;
BitField<4, 1, u32> depth_clamp_far;
} view_volume_clip_control;
INSERT_PADDING_WORDS(0x21);
struct { struct {
u32 enable; u32 enable;
LogicOperation operation; LogicOperation operation;
@ -1224,6 +1231,7 @@ ASSERT_REG_POSITION(instanced_arrays, 0x620);
ASSERT_REG_POSITION(cull, 0x646); ASSERT_REG_POSITION(cull, 0x646);
ASSERT_REG_POSITION(pixel_center_integer, 0x649); ASSERT_REG_POSITION(pixel_center_integer, 0x649);
ASSERT_REG_POSITION(viewport_transform_enabled, 0x64B); ASSERT_REG_POSITION(viewport_transform_enabled, 0x64B);
ASSERT_REG_POSITION(view_volume_clip_control, 0x64F);
ASSERT_REG_POSITION(logic_op, 0x671); ASSERT_REG_POSITION(logic_op, 0x671);
ASSERT_REG_POSITION(clear_buffers, 0x674); ASSERT_REG_POSITION(clear_buffers, 0x674);
ASSERT_REG_POSITION(color_mask, 0x680); ASSERT_REG_POSITION(color_mask, 0x680);

View file

@ -113,10 +113,24 @@ RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& window, ScreenInfo
glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &uniform_buffer_alignment); glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &uniform_buffer_alignment);
LOG_CRITICAL(Render_OpenGL, "Sync fixed function OpenGL state here!"); LOG_CRITICAL(Render_OpenGL, "Sync fixed function OpenGL state here!");
CheckExtensions();
} }
RasterizerOpenGL::~RasterizerOpenGL() {} RasterizerOpenGL::~RasterizerOpenGL() {}
void RasterizerOpenGL::CheckExtensions() {
if (!GLAD_GL_ARB_texture_filter_anisotropic && !GLAD_GL_EXT_texture_filter_anisotropic) {
LOG_WARNING(
Render_OpenGL,
"Anisotropic filter is not supported! This can cause graphical issues in some games.");
}
if (!GLAD_GL_ARB_buffer_storage) {
LOG_WARNING(
Render_OpenGL,
"Buffer storage control is not supported! This can cause performance degradation.");
}
}
void RasterizerOpenGL::SetupVertexFormat() { void RasterizerOpenGL::SetupVertexFormat() {
auto& gpu = Core::System::GetInstance().GPU().Maxwell3D(); auto& gpu = Core::System::GetInstance().GPU().Maxwell3D();
const auto& regs = gpu.regs; const auto& regs = gpu.regs;
@ -1007,6 +1021,8 @@ void RasterizerOpenGL::SyncViewport(OpenGLState& current_state) {
viewport.depth_range_far = regs.viewports[i].depth_range_far; viewport.depth_range_far = regs.viewports[i].depth_range_far;
viewport.depth_range_near = regs.viewports[i].depth_range_near; viewport.depth_range_near = regs.viewports[i].depth_range_near;
} }
state.depth_clamp.far_plane = regs.view_volume_clip_control.depth_clamp_far != 0;
state.depth_clamp.near_plane = regs.view_volume_clip_control.depth_clamp_near != 0;
} }
void RasterizerOpenGL::SyncClipEnabled() { void RasterizerOpenGL::SyncClipEnabled() {

View file

@ -189,6 +189,10 @@ private:
/// Check asserts for alpha testing. /// Check asserts for alpha testing.
void CheckAlphaTests(); void CheckAlphaTests();
/// Check for extension that are not strictly required
/// but are needed for correct emulation
void CheckExtensions();
bool has_ARB_direct_state_access = false; bool has_ARB_direct_state_access = false;
bool has_ARB_multi_bind = false; bool has_ARB_multi_bind = false;

View file

@ -92,7 +92,8 @@ OpenGLState::OpenGLState() {
point.size = 1; point.size = 1;
fragment_color_clamp.enabled = false; fragment_color_clamp.enabled = false;
depth_clamp.far_plane = false;
depth_clamp.near_plane = false;
polygon_offset.fill_enable = false; polygon_offset.fill_enable = false;
polygon_offset.line_enable = false; polygon_offset.line_enable = false;
polygon_offset.point_enable = false; polygon_offset.point_enable = false;
@ -147,7 +148,7 @@ void OpenGLState::ApplyCulling() const {
} }
void OpenGLState::ApplyColorMask() const { void OpenGLState::ApplyColorMask() const {
if (GLAD_GL_ARB_viewport_array && independant_blend.enabled) { if (independant_blend.enabled) {
for (size_t i = 0; i < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets; i++) { for (size_t i = 0; i < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets; i++) {
const auto& updated = color_mask[i]; const auto& updated = color_mask[i];
const auto& current = cur_state.color_mask[i]; const auto& current = cur_state.color_mask[i];
@ -264,7 +265,7 @@ void OpenGLState::EmulateViewportWithScissor() {
} }
void OpenGLState::ApplyViewport() const { void OpenGLState::ApplyViewport() const {
if (GLAD_GL_ARB_viewport_array && geometry_shaders.enabled) { if (geometry_shaders.enabled) {
for (GLuint i = 0; i < static_cast<GLuint>(Tegra::Engines::Maxwell3D::Regs::NumViewports); for (GLuint i = 0; i < static_cast<GLuint>(Tegra::Engines::Maxwell3D::Regs::NumViewports);
i++) { i++) {
const auto& current = cur_state.viewports[i]; const auto& current = cur_state.viewports[i];
@ -525,6 +526,21 @@ void OpenGLState::ApplyVertexBufferState() const {
} }
} }
void OpenGLState::ApplyDepthClamp() const {
if (depth_clamp.far_plane == cur_state.depth_clamp.far_plane &&
depth_clamp.near_plane == cur_state.depth_clamp.near_plane) {
return;
}
if (depth_clamp.far_plane != depth_clamp.near_plane) {
UNIMPLEMENTED_MSG("Unimplemented Depth Clamp Separation!");
}
if (depth_clamp.far_plane || depth_clamp.near_plane) {
glEnable(GL_DEPTH_CLAMP);
} else {
glDisable(GL_DEPTH_CLAMP);
}
}
void OpenGLState::Apply() const { void OpenGLState::Apply() const {
ApplyFramebufferState(); ApplyFramebufferState();
ApplyVertexBufferState(); ApplyVertexBufferState();
@ -556,11 +572,9 @@ void OpenGLState::Apply() const {
if (point.size != cur_state.point.size) { if (point.size != cur_state.point.size) {
glPointSize(point.size); glPointSize(point.size);
} }
if (GLAD_GL_ARB_color_buffer_float) { if (fragment_color_clamp.enabled != cur_state.fragment_color_clamp.enabled) {
if (fragment_color_clamp.enabled != cur_state.fragment_color_clamp.enabled) { glClampColor(GL_CLAMP_FRAGMENT_COLOR_ARB,
glClampColor(GL_CLAMP_FRAGMENT_COLOR_ARB, fragment_color_clamp.enabled ? GL_TRUE : GL_FALSE);
fragment_color_clamp.enabled ? GL_TRUE : GL_FALSE);
}
} }
if (multisample_control.alpha_to_coverage != cur_state.multisample_control.alpha_to_coverage) { if (multisample_control.alpha_to_coverage != cur_state.multisample_control.alpha_to_coverage) {
if (multisample_control.alpha_to_coverage) { if (multisample_control.alpha_to_coverage) {
@ -576,7 +590,7 @@ void OpenGLState::Apply() const {
glDisable(GL_SAMPLE_ALPHA_TO_ONE); glDisable(GL_SAMPLE_ALPHA_TO_ONE);
} }
} }
ApplyDepthClamp();
ApplyColorMask(); ApplyColorMask();
ApplyViewport(); ApplyViewport();
ApplyStencilTest(); ApplyStencilTest();

View file

@ -48,6 +48,11 @@ public:
bool enabled; // GL_CLAMP_FRAGMENT_COLOR_ARB bool enabled; // GL_CLAMP_FRAGMENT_COLOR_ARB
} fragment_color_clamp; } fragment_color_clamp;
struct {
bool far_plane;
bool near_plane;
} depth_clamp; // GL_DEPTH_CLAMP
struct { struct {
bool enabled; // viewports arrays are only supported when geometry shaders are enabled. bool enabled; // viewports arrays are only supported when geometry shaders are enabled.
} geometry_shaders; } geometry_shaders;
@ -235,6 +240,7 @@ private:
void ApplyLogicOp() const; void ApplyLogicOp() const;
void ApplyTextures() const; void ApplyTextures() const;
void ApplySamplers() const; void ApplySamplers() const;
void ApplyDepthClamp() const;
void ApplyPolygonOffset() const; void ApplyPolygonOffset() const;
}; };