diff options
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 28 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 9 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_gen.cpp | 80 | 
3 files changed, 83 insertions, 34 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index aa95ef21d..7b0cd1b66 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -169,6 +169,8 @@ RasterizerOpenGL::RasterizerOpenGL() : shader_dirty(true) {      glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, proctex_diff_lut_buffer.handle);      // Sync fixed function OpenGL state +    SyncClipEnabled(); +    SyncClipCoef();      SyncCullMode();      SyncBlendEnabled();      SyncBlendFuncs(); @@ -401,6 +403,18 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) {          SyncCullMode();          break; +    // Clipping plane +    case PICA_REG_INDEX(rasterizer.clip_enable): +        SyncClipEnabled(); +        break; + +    case PICA_REG_INDEX_WORKAROUND(rasterizer.clip_coef[0], 0x48): +    case PICA_REG_INDEX_WORKAROUND(rasterizer.clip_coef[1], 0x49): +    case PICA_REG_INDEX_WORKAROUND(rasterizer.clip_coef[2], 0x4a): +    case PICA_REG_INDEX_WORKAROUND(rasterizer.clip_coef[3], 0x4b): +        SyncClipCoef(); +        break; +      // Depth modifiers      case PICA_REG_INDEX(rasterizer.viewport_depth_range):          SyncDepthScale(); @@ -1280,6 +1294,20 @@ void RasterizerOpenGL::SetShader() {      }  } +void RasterizerOpenGL::SyncClipEnabled() { +    state.clip_distance[1] = Pica::g_state.regs.rasterizer.clip_enable != 0; +} + +void RasterizerOpenGL::SyncClipCoef() { +    const auto raw_clip_coef = Pica::g_state.regs.rasterizer.GetClipCoef(); +    const GLvec4 new_clip_coef = {raw_clip_coef.x.ToFloat32(), raw_clip_coef.y.ToFloat32(), +                                  raw_clip_coef.z.ToFloat32(), raw_clip_coef.w.ToFloat32()}; +    if (new_clip_coef != uniform_block_data.data.clip_coef) { +        uniform_block_data.data.clip_coef = new_clip_coef; +        uniform_block_data.dirty = true; +    } +} +  void RasterizerOpenGL::SyncCullMode() {      const auto& regs = Pica::g_state.regs; diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 78e218efe..46c62961c 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -151,14 +151,21 @@ private:          LightSrc light_src[8];          alignas(16) GLvec4 const_color[6]; // A vec4 color for each of the six tev stages          alignas(16) GLvec4 tev_combiner_buffer_color; +        alignas(16) GLvec4 clip_coef;      };      static_assert( -        sizeof(UniformData) == 0x460, +        sizeof(UniformData) == 0x470,          "The size of the UniformData structure has changed, update the structure in the shader");      static_assert(sizeof(UniformData) < 16384,                    "UniformData structure must be less than 16kb as per the OpenGL spec"); +    /// Syncs the clip enabled status to match the PICA register +    void SyncClipEnabled(); + +    /// Syncs the clip coefficients to match the PICA register +    void SyncClipCoef(); +      /// Sets the OpenGL shader in accordance with the current PICA register state      void SetShader(); diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp index 015e69da9..aa60b2e7f 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.cpp +++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp @@ -24,6 +24,42 @@ using TevStageConfig = TexturingRegs::TevStageConfig;  namespace GLShader { +static const std::string UniformBlockDef = R"( +#define NUM_TEV_STAGES 6 +#define NUM_LIGHTS 8 + +struct LightSrc { +    vec3 specular_0; +    vec3 specular_1; +    vec3 diffuse; +    vec3 ambient; +    vec3 position; +    vec3 spot_direction; +    float dist_atten_bias; +    float dist_atten_scale; +}; + +layout (std140) uniform shader_data { +    vec2 framebuffer_scale; +    int alphatest_ref; +    float depth_scale; +    float depth_offset; +    int scissor_x1; +    int scissor_y1; +    int scissor_x2; +    int scissor_y2; +    vec3 fog_color; +    vec2 proctex_noise_f; +    vec2 proctex_noise_a; +    vec2 proctex_noise_p; +    vec3 lighting_global_ambient; +    LightSrc light_src[NUM_LIGHTS]; +    vec4 const_color[NUM_TEV_STAGES]; +    vec4 tev_combiner_buffer_color; +    vec4 clip_coef; +}; +)"; +  PicaShaderConfig PicaShaderConfig::BuildFromRegs(const Pica::Regs& regs) {      PicaShaderConfig res; @@ -1008,8 +1044,6 @@ std::string GenerateFragmentShader(const PicaShaderConfig& config) {      std::string out = R"(  #version 330 core -#define NUM_TEV_STAGES 6 -#define NUM_LIGHTS 8  in vec4 primary_color;  in vec2 texcoord[3]; @@ -1021,36 +1055,6 @@ in vec4 gl_FragCoord;  out vec4 color; -struct LightSrc { -    vec3 specular_0; -    vec3 specular_1; -    vec3 diffuse; -    vec3 ambient; -    vec3 position; -    vec3 spot_direction; -    float dist_atten_bias; -    float dist_atten_scale; -}; - -layout (std140) uniform shader_data { -    vec2 framebuffer_scale; -    int alphatest_ref; -    float depth_scale; -    float depth_offset; -    int scissor_x1; -    int scissor_y1; -    int scissor_x2; -    int scissor_y2; -    vec3 fog_color; -    vec2 proctex_noise_f; -    vec2 proctex_noise_a; -    vec2 proctex_noise_p; -    vec3 lighting_global_ambient; -    LightSrc light_src[NUM_LIGHTS]; -    vec4 const_color[NUM_TEV_STAGES]; -    vec4 tev_combiner_buffer_color; -}; -  uniform sampler2D tex[3];  uniform samplerBuffer lighting_lut;  uniform samplerBuffer fog_lut; @@ -1059,7 +1063,11 @@ uniform samplerBuffer proctex_color_map;  uniform samplerBuffer proctex_alpha_map;  uniform samplerBuffer proctex_lut;  uniform samplerBuffer proctex_diff_lut; +)"; + +    out += UniformBlockDef; +    out += R"(  // Rotate the vector v by the quaternion q  vec3 quaternion_rotate(vec4 q, vec3 v) {      return v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v); @@ -1190,6 +1198,12 @@ out float texcoord0_w;  out vec4 normquat;  out vec3 view; +)"; + +    out += UniformBlockDef; + +    out += R"( +  void main() {      primary_color = vert_color;      texcoord[0] = vert_texcoord0; @@ -1200,7 +1214,7 @@ void main() {      view = vert_view;      gl_Position = vert_position;      gl_ClipDistance[0] = -vert_position.z; // fixed PICA clipping plane z <= 0 -    // TODO (wwylele): calculate gl_ClipDistance[1] from user-defined clipping plane +    gl_ClipDistance[1] = dot(clip_coef, vert_position);  }  )";  | 
