Просмотр исходного кода

Merge pull request #1591 from bunnei/depth-range

gl_rasterizer: Implement depth range.
bunnei 7 лет назад
Родитель
Сommit
1f98dc30ea

+ 19 - 1
src/video_core/engines/maxwell_3d.cpp

@@ -3,6 +3,7 @@
 // Refer to the license.txt file included.
 // Refer to the license.txt file included.
 
 
 #include <cinttypes>
 #include <cinttypes>
+#include <cstring>
 #include "common/assert.h"
 #include "common/assert.h"
 #include "core/core.h"
 #include "core/core.h"
 #include "core/core_timing.h"
 #include "core/core_timing.h"
@@ -19,7 +20,24 @@ namespace Tegra::Engines {
 constexpr u32 MacroRegistersStart = 0xE00;
 constexpr u32 MacroRegistersStart = 0xE00;
 
 
 Maxwell3D::Maxwell3D(VideoCore::RasterizerInterface& rasterizer, MemoryManager& memory_manager)
 Maxwell3D::Maxwell3D(VideoCore::RasterizerInterface& rasterizer, MemoryManager& memory_manager)
-    : memory_manager(memory_manager), rasterizer{rasterizer}, macro_interpreter(*this) {}
+    : memory_manager(memory_manager), rasterizer{rasterizer}, macro_interpreter(*this) {
+    InitializeRegisterDefaults();
+}
+
+void Maxwell3D::InitializeRegisterDefaults() {
+    // Initializes registers to their default values - what games expect them to be at boot. This is
+    // for certain registers that may not be explicitly set by games.
+
+    // Reset all registers to zero
+    std::memset(&regs, 0, sizeof(regs));
+
+    // Depth range near/far is not always set, but is expected to be the default 0.0f, 1.0f. This is
+    // needed for ARMS.
+    for (std::size_t viewport{}; viewport < Regs::NumViewports; ++viewport) {
+        regs.viewport[viewport].depth_range_near = 0.0f;
+        regs.viewport[viewport].depth_range_far = 1.0f;
+    }
+}
 
 
 void Maxwell3D::CallMacroMethod(u32 method, std::vector<u32> parameters) {
 void Maxwell3D::CallMacroMethod(u32 method, std::vector<u32> parameters) {
     // Reset the current macro.
     // Reset the current macro.

+ 2 - 0
src/video_core/engines/maxwell_3d.h

@@ -984,6 +984,8 @@ public:
     Texture::FullTextureInfo GetStageTexture(Regs::ShaderStage stage, std::size_t offset) const;
     Texture::FullTextureInfo GetStageTexture(Regs::ShaderStage stage, std::size_t offset) const;
 
 
 private:
 private:
+    void InitializeRegisterDefaults();
+
     VideoCore::RasterizerInterface& rasterizer;
     VideoCore::RasterizerInterface& rasterizer;
 
 
     std::unordered_map<u32, std::vector<u32>> uploaded_macros;
     std::unordered_map<u32, std::vector<u32>> uploaded_macros;

+ 5 - 5
src/video_core/renderer_opengl/gl_rasterizer.cpp

@@ -570,6 +570,7 @@ void RasterizerOpenGL::DrawArrays() {
     SyncBlendState();
     SyncBlendState();
     SyncLogicOpState();
     SyncLogicOpState();
     SyncCullMode();
     SyncCullMode();
+    SyncDepthRange();
     SyncScissorTest();
     SyncScissorTest();
     // Alpha Testing is synced on shaders.
     // Alpha Testing is synced on shaders.
     SyncTransformFeedback();
     SyncTransformFeedback();
@@ -923,12 +924,11 @@ void RasterizerOpenGL::SyncCullMode() {
     }
     }
 }
 }
 
 
-void RasterizerOpenGL::SyncDepthScale() {
-    UNREACHABLE();
-}
+void RasterizerOpenGL::SyncDepthRange() {
+    const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
 
 
-void RasterizerOpenGL::SyncDepthOffset() {
-    UNREACHABLE();
+    state.depth.depth_range_near = regs.viewport->depth_range_near;
+    state.depth.depth_range_far = regs.viewport->depth_range_far;
 }
 }
 
 
 void RasterizerOpenGL::SyncDepthTestState() {
 void RasterizerOpenGL::SyncDepthTestState() {

+ 2 - 5
src/video_core/renderer_opengl/gl_rasterizer.h

@@ -144,11 +144,8 @@ private:
     /// Syncs the cull mode to match the guest state
     /// Syncs the cull mode to match the guest state
     void SyncCullMode();
     void SyncCullMode();
 
 
-    /// Syncs the depth scale to match the guest state
-    void SyncDepthScale();
-
-    /// Syncs the depth offset to match the guest state
-    void SyncDepthOffset();
+    /// Syncs the depth range to match the guest state
+    void SyncDepthRange();
 
 
     /// Syncs the depth test state to match the guest state
     /// Syncs the depth test state to match the guest state
     void SyncDepthTestState();
     void SyncDepthTestState();

+ 8 - 0
src/video_core/renderer_opengl/gl_state.cpp

@@ -21,6 +21,8 @@ OpenGLState::OpenGLState() {
     depth.test_enabled = false;
     depth.test_enabled = false;
     depth.test_func = GL_LESS;
     depth.test_func = GL_LESS;
     depth.write_mask = GL_TRUE;
     depth.write_mask = GL_TRUE;
+    depth.depth_range_near = 0.0f;
+    depth.depth_range_far = 1.0f;
 
 
     color_mask.red_enabled = GL_TRUE;
     color_mask.red_enabled = GL_TRUE;
     color_mask.green_enabled = GL_TRUE;
     color_mask.green_enabled = GL_TRUE;
@@ -119,6 +121,12 @@ void OpenGLState::Apply() const {
         glDepthMask(depth.write_mask);
         glDepthMask(depth.write_mask);
     }
     }
 
 
+    // Depth range
+    if (depth.depth_range_near != cur_state.depth.depth_range_near ||
+        depth.depth_range_far != cur_state.depth.depth_range_far) {
+        glDepthRange(depth.depth_range_near, depth.depth_range_far);
+    }
+
     // Color mask
     // Color mask
     if (color_mask.red_enabled != cur_state.color_mask.red_enabled ||
     if (color_mask.red_enabled != cur_state.color_mask.red_enabled ||
         color_mask.green_enabled != cur_state.color_mask.green_enabled ||
         color_mask.green_enabled != cur_state.color_mask.green_enabled ||

+ 5 - 3
src/video_core/renderer_opengl/gl_state.h

@@ -42,9 +42,11 @@ public:
     } cull;
     } cull;
 
 
     struct {
     struct {
-        bool test_enabled;    // GL_DEPTH_TEST
-        GLenum test_func;     // GL_DEPTH_FUNC
-        GLboolean write_mask; // GL_DEPTH_WRITEMASK
+        bool test_enabled;        // GL_DEPTH_TEST
+        GLenum test_func;         // GL_DEPTH_FUNC
+        GLboolean write_mask;     // GL_DEPTH_WRITEMASK
+        GLfloat depth_range_near; // GL_DEPTH_RANGE
+        GLfloat depth_range_far;  // GL_DEPTH_RANGE
     } depth;
     } depth;
 
 
     struct {
     struct {