diff options
| author | 2017-08-22 09:49:53 +0300 | |
|---|---|---|
| committer | 2017-08-25 07:26:45 +0300 | |
| commit | addbcd5784c8195f49cecc20834537c80d1c8c72 (patch) | |
| tree | 1a21dffd2eed5d337f6687739ea163503e298bf8 /src | |
| parent | SwRasterizer: implement custom clip plane (diff) | |
| download | yuzu-addbcd5784c8195f49cecc20834537c80d1c8c72.tar.gz yuzu-addbcd5784c8195f49cecc20834537c80d1c8c72.tar.xz yuzu-addbcd5784c8195f49cecc20834537c80d1c8c72.zip | |
gl_rasterizer: implement custom clip plane
Diffstat (limited to '')
| -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) { | |||
| 169 | glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, proctex_diff_lut_buffer.handle); | 169 | glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, proctex_diff_lut_buffer.handle); |
| 170 | 170 | ||
| 171 | // Sync fixed function OpenGL state | 171 | // Sync fixed function OpenGL state |
| 172 | SyncClipEnabled(); | ||
| 173 | SyncClipCoef(); | ||
| 172 | SyncCullMode(); | 174 | SyncCullMode(); |
| 173 | SyncBlendEnabled(); | 175 | SyncBlendEnabled(); |
| 174 | SyncBlendFuncs(); | 176 | SyncBlendFuncs(); |
| @@ -401,6 +403,18 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) { | |||
| 401 | SyncCullMode(); | 403 | SyncCullMode(); |
| 402 | break; | 404 | break; |
| 403 | 405 | ||
| 406 | // Clipping plane | ||
| 407 | case PICA_REG_INDEX(rasterizer.clip_enable): | ||
| 408 | SyncClipEnabled(); | ||
| 409 | break; | ||
| 410 | |||
| 411 | case PICA_REG_INDEX_WORKAROUND(rasterizer.clip_coef[0], 0x48): | ||
| 412 | case PICA_REG_INDEX_WORKAROUND(rasterizer.clip_coef[1], 0x49): | ||
| 413 | case PICA_REG_INDEX_WORKAROUND(rasterizer.clip_coef[2], 0x4a): | ||
| 414 | case PICA_REG_INDEX_WORKAROUND(rasterizer.clip_coef[3], 0x4b): | ||
| 415 | SyncClipCoef(); | ||
| 416 | break; | ||
| 417 | |||
| 404 | // Depth modifiers | 418 | // Depth modifiers |
| 405 | case PICA_REG_INDEX(rasterizer.viewport_depth_range): | 419 | case PICA_REG_INDEX(rasterizer.viewport_depth_range): |
| 406 | SyncDepthScale(); | 420 | SyncDepthScale(); |
| @@ -1280,6 +1294,20 @@ void RasterizerOpenGL::SetShader() { | |||
| 1280 | } | 1294 | } |
| 1281 | } | 1295 | } |
| 1282 | 1296 | ||
| 1297 | void RasterizerOpenGL::SyncClipEnabled() { | ||
| 1298 | state.clip_distance[1] = Pica::g_state.regs.rasterizer.clip_enable != 0; | ||
| 1299 | } | ||
| 1300 | |||
| 1301 | void RasterizerOpenGL::SyncClipCoef() { | ||
| 1302 | const auto raw_clip_coef = Pica::g_state.regs.rasterizer.GetClipCoef(); | ||
| 1303 | const GLvec4 new_clip_coef = {raw_clip_coef.x.ToFloat32(), raw_clip_coef.y.ToFloat32(), | ||
| 1304 | raw_clip_coef.z.ToFloat32(), raw_clip_coef.w.ToFloat32()}; | ||
| 1305 | if (new_clip_coef != uniform_block_data.data.clip_coef) { | ||
| 1306 | uniform_block_data.data.clip_coef = new_clip_coef; | ||
| 1307 | uniform_block_data.dirty = true; | ||
| 1308 | } | ||
| 1309 | } | ||
| 1310 | |||
| 1283 | void RasterizerOpenGL::SyncCullMode() { | 1311 | void RasterizerOpenGL::SyncCullMode() { |
| 1284 | const auto& regs = Pica::g_state.regs; | 1312 | const auto& regs = Pica::g_state.regs; |
| 1285 | 1313 | ||
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: | |||
| 151 | LightSrc light_src[8]; | 151 | LightSrc light_src[8]; |
| 152 | alignas(16) GLvec4 const_color[6]; // A vec4 color for each of the six tev stages | 152 | alignas(16) GLvec4 const_color[6]; // A vec4 color for each of the six tev stages |
| 153 | alignas(16) GLvec4 tev_combiner_buffer_color; | 153 | alignas(16) GLvec4 tev_combiner_buffer_color; |
| 154 | alignas(16) GLvec4 clip_coef; | ||
| 154 | }; | 155 | }; |
| 155 | 156 | ||
| 156 | static_assert( | 157 | static_assert( |
| 157 | sizeof(UniformData) == 0x460, | 158 | sizeof(UniformData) == 0x470, |
| 158 | "The size of the UniformData structure has changed, update the structure in the shader"); | 159 | "The size of the UniformData structure has changed, update the structure in the shader"); |
| 159 | static_assert(sizeof(UniformData) < 16384, | 160 | static_assert(sizeof(UniformData) < 16384, |
| 160 | "UniformData structure must be less than 16kb as per the OpenGL spec"); | 161 | "UniformData structure must be less than 16kb as per the OpenGL spec"); |
| 161 | 162 | ||
| 163 | /// Syncs the clip enabled status to match the PICA register | ||
| 164 | void SyncClipEnabled(); | ||
| 165 | |||
| 166 | /// Syncs the clip coefficients to match the PICA register | ||
| 167 | void SyncClipCoef(); | ||
| 168 | |||
| 162 | /// Sets the OpenGL shader in accordance with the current PICA register state | 169 | /// Sets the OpenGL shader in accordance with the current PICA register state |
| 163 | void SetShader(); | 170 | void SetShader(); |
| 164 | 171 | ||
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; | |||
| 24 | 24 | ||
| 25 | namespace GLShader { | 25 | namespace GLShader { |
| 26 | 26 | ||
| 27 | static const std::string UniformBlockDef = R"( | ||
| 28 | #define NUM_TEV_STAGES 6 | ||
| 29 | #define NUM_LIGHTS 8 | ||
| 30 | |||
| 31 | struct LightSrc { | ||
| 32 | vec3 specular_0; | ||
| 33 | vec3 specular_1; | ||
| 34 | vec3 diffuse; | ||
| 35 | vec3 ambient; | ||
| 36 | vec3 position; | ||
| 37 | vec3 spot_direction; | ||
| 38 | float dist_atten_bias; | ||
| 39 | float dist_atten_scale; | ||
| 40 | }; | ||
| 41 | |||
| 42 | layout (std140) uniform shader_data { | ||
| 43 | vec2 framebuffer_scale; | ||
| 44 | int alphatest_ref; | ||
| 45 | float depth_scale; | ||
| 46 | float depth_offset; | ||
| 47 | int scissor_x1; | ||
| 48 | int scissor_y1; | ||
| 49 | int scissor_x2; | ||
| 50 | int scissor_y2; | ||
| 51 | vec3 fog_color; | ||
| 52 | vec2 proctex_noise_f; | ||
| 53 | vec2 proctex_noise_a; | ||
| 54 | vec2 proctex_noise_p; | ||
| 55 | vec3 lighting_global_ambient; | ||
| 56 | LightSrc light_src[NUM_LIGHTS]; | ||
| 57 | vec4 const_color[NUM_TEV_STAGES]; | ||
| 58 | vec4 tev_combiner_buffer_color; | ||
| 59 | vec4 clip_coef; | ||
| 60 | }; | ||
| 61 | )"; | ||
| 62 | |||
| 27 | PicaShaderConfig PicaShaderConfig::BuildFromRegs(const Pica::Regs& regs) { | 63 | PicaShaderConfig PicaShaderConfig::BuildFromRegs(const Pica::Regs& regs) { |
| 28 | PicaShaderConfig res; | 64 | PicaShaderConfig res; |
| 29 | 65 | ||
| @@ -1008,8 +1044,6 @@ std::string GenerateFragmentShader(const PicaShaderConfig& config) { | |||
| 1008 | 1044 | ||
| 1009 | std::string out = R"( | 1045 | std::string out = R"( |
| 1010 | #version 330 core | 1046 | #version 330 core |
| 1011 | #define NUM_TEV_STAGES 6 | ||
| 1012 | #define NUM_LIGHTS 8 | ||
| 1013 | 1047 | ||
| 1014 | in vec4 primary_color; | 1048 | in vec4 primary_color; |
| 1015 | in vec2 texcoord[3]; | 1049 | in vec2 texcoord[3]; |
| @@ -1021,36 +1055,6 @@ in vec4 gl_FragCoord; | |||
| 1021 | 1055 | ||
| 1022 | out vec4 color; | 1056 | out vec4 color; |
| 1023 | 1057 | ||
| 1024 | struct LightSrc { | ||
| 1025 | vec3 specular_0; | ||
| 1026 | vec3 specular_1; | ||
| 1027 | vec3 diffuse; | ||
| 1028 | vec3 ambient; | ||
| 1029 | vec3 position; | ||
| 1030 | vec3 spot_direction; | ||
| 1031 | float dist_atten_bias; | ||
| 1032 | float dist_atten_scale; | ||
| 1033 | }; | ||
| 1034 | |||
| 1035 | layout (std140) uniform shader_data { | ||
| 1036 | vec2 framebuffer_scale; | ||
| 1037 | int alphatest_ref; | ||
| 1038 | float depth_scale; | ||
| 1039 | float depth_offset; | ||
| 1040 | int scissor_x1; | ||
| 1041 | int scissor_y1; | ||
| 1042 | int scissor_x2; | ||
| 1043 | int scissor_y2; | ||
| 1044 | vec3 fog_color; | ||
| 1045 | vec2 proctex_noise_f; | ||
| 1046 | vec2 proctex_noise_a; | ||
| 1047 | vec2 proctex_noise_p; | ||
| 1048 | vec3 lighting_global_ambient; | ||
| 1049 | LightSrc light_src[NUM_LIGHTS]; | ||
| 1050 | vec4 const_color[NUM_TEV_STAGES]; | ||
| 1051 | vec4 tev_combiner_buffer_color; | ||
| 1052 | }; | ||
| 1053 | |||
| 1054 | uniform sampler2D tex[3]; | 1058 | uniform sampler2D tex[3]; |
| 1055 | uniform samplerBuffer lighting_lut; | 1059 | uniform samplerBuffer lighting_lut; |
| 1056 | uniform samplerBuffer fog_lut; | 1060 | uniform samplerBuffer fog_lut; |
| @@ -1059,7 +1063,11 @@ uniform samplerBuffer proctex_color_map; | |||
| 1059 | uniform samplerBuffer proctex_alpha_map; | 1063 | uniform samplerBuffer proctex_alpha_map; |
| 1060 | uniform samplerBuffer proctex_lut; | 1064 | uniform samplerBuffer proctex_lut; |
| 1061 | uniform samplerBuffer proctex_diff_lut; | 1065 | uniform samplerBuffer proctex_diff_lut; |
| 1066 | )"; | ||
| 1067 | |||
| 1068 | out += UniformBlockDef; | ||
| 1062 | 1069 | ||
| 1070 | out += R"( | ||
| 1063 | // Rotate the vector v by the quaternion q | 1071 | // Rotate the vector v by the quaternion q |
| 1064 | vec3 quaternion_rotate(vec4 q, vec3 v) { | 1072 | vec3 quaternion_rotate(vec4 q, vec3 v) { |
| 1065 | return v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v); | 1073 | return v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v); |
| @@ -1190,6 +1198,12 @@ out float texcoord0_w; | |||
| 1190 | out vec4 normquat; | 1198 | out vec4 normquat; |
| 1191 | out vec3 view; | 1199 | out vec3 view; |
| 1192 | 1200 | ||
| 1201 | )"; | ||
| 1202 | |||
| 1203 | out += UniformBlockDef; | ||
| 1204 | |||
| 1205 | out += R"( | ||
| 1206 | |||
| 1193 | void main() { | 1207 | void main() { |
| 1194 | primary_color = vert_color; | 1208 | primary_color = vert_color; |
| 1195 | texcoord[0] = vert_texcoord0; | 1209 | texcoord[0] = vert_texcoord0; |
| @@ -1200,7 +1214,7 @@ void main() { | |||
| 1200 | view = vert_view; | 1214 | view = vert_view; |
| 1201 | gl_Position = vert_position; | 1215 | gl_Position = vert_position; |
| 1202 | gl_ClipDistance[0] = -vert_position.z; // fixed PICA clipping plane z <= 0 | 1216 | gl_ClipDistance[0] = -vert_position.z; // fixed PICA clipping plane z <= 0 |
| 1203 | // TODO (wwylele): calculate gl_ClipDistance[1] from user-defined clipping plane | 1217 | gl_ClipDistance[1] = dot(clip_coef, vert_position); |
| 1204 | } | 1218 | } |
| 1205 | )"; | 1219 | )"; |
| 1206 | 1220 | ||