summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar wwylele2017-08-22 09:49:53 +0300
committerGravatar wwylele2017-08-25 07:26:45 +0300
commitaddbcd5784c8195f49cecc20834537c80d1c8c72 (patch)
tree1a21dffd2eed5d337f6687739ea163503e298bf8 /src
parentSwRasterizer: implement custom clip plane (diff)
downloadyuzu-addbcd5784c8195f49cecc20834537c80d1c8c72.tar.gz
yuzu-addbcd5784c8195f49cecc20834537c80d1c8c72.tar.xz
yuzu-addbcd5784c8195f49cecc20834537c80d1c8c72.zip
gl_rasterizer: implement custom clip plane
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp28
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h9
-rw-r--r--src/video_core/renderer_opengl/gl_shader_gen.cpp80
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
1297void RasterizerOpenGL::SyncClipEnabled() {
1298 state.clip_distance[1] = Pica::g_state.regs.rasterizer.clip_enable != 0;
1299}
1300
1301void 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
1283void RasterizerOpenGL::SyncCullMode() { 1311void 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
25namespace GLShader { 25namespace GLShader {
26 26
27static const std::string UniformBlockDef = R"(
28#define NUM_TEV_STAGES 6
29#define NUM_LIGHTS 8
30
31struct 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
42layout (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
27PicaShaderConfig PicaShaderConfig::BuildFromRegs(const Pica::Regs& regs) { 63PicaShaderConfig 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
1014in vec4 primary_color; 1048in vec4 primary_color;
1015in vec2 texcoord[3]; 1049in vec2 texcoord[3];
@@ -1021,36 +1055,6 @@ in vec4 gl_FragCoord;
1021 1055
1022out vec4 color; 1056out vec4 color;
1023 1057
1024struct 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
1035layout (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
1054uniform sampler2D tex[3]; 1058uniform sampler2D tex[3];
1055uniform samplerBuffer lighting_lut; 1059uniform samplerBuffer lighting_lut;
1056uniform samplerBuffer fog_lut; 1060uniform samplerBuffer fog_lut;
@@ -1059,7 +1063,11 @@ uniform samplerBuffer proctex_color_map;
1059uniform samplerBuffer proctex_alpha_map; 1063uniform samplerBuffer proctex_alpha_map;
1060uniform samplerBuffer proctex_lut; 1064uniform samplerBuffer proctex_lut;
1061uniform samplerBuffer proctex_diff_lut; 1065uniform 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
1064vec3 quaternion_rotate(vec4 q, vec3 v) { 1072vec3 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;
1190out vec4 normquat; 1198out vec4 normquat;
1191out vec3 view; 1199out vec3 view;
1192 1200
1201)";
1202
1203 out += UniformBlockDef;
1204
1205 out += R"(
1206
1193void main() { 1207void 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