diff options
| author | 2020-06-24 01:51:15 -0300 | |
|---|---|---|
| committer | 2020-06-24 01:51:15 -0300 | |
| commit | b66ccaa37615352a5a8b97e20ce6e6751d136b18 (patch) | |
| tree | 783967c26d0c5a4e2859a99bc8ca14ff160d2ec5 /src | |
| parent | Merge pull request #4138 from Morph1984/GyroscopeZeroDriftMode (diff) | |
| parent | gl_shader_decompiler: Enable GL_EXT_texture_shadow_lod if available (diff) | |
| download | yuzu-b66ccaa37615352a5a8b97e20ce6e6751d136b18.tar.gz yuzu-b66ccaa37615352a5a8b97e20ce6e6751d136b18.tar.xz yuzu-b66ccaa37615352a5a8b97e20ce6e6751d136b18.zip | |
Merge pull request #4129 from Morph1984/texture-shadow-lod-workaround
gl_shader_decompiler: Workaround textureLod when GL_EXT_texture_shadow_lod is not available
Diffstat (limited to '')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_device.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_device.h | 5 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 50 |
3 files changed, 50 insertions, 7 deletions
diff --git a/src/video_core/renderer_opengl/gl_device.cpp b/src/video_core/renderer_opengl/gl_device.cpp index b31d604e4..1011c7738 100644 --- a/src/video_core/renderer_opengl/gl_device.cpp +++ b/src/video_core/renderer_opengl/gl_device.cpp | |||
| @@ -216,6 +216,7 @@ Device::Device() | |||
| 216 | has_shader_ballot = GLAD_GL_ARB_shader_ballot; | 216 | has_shader_ballot = GLAD_GL_ARB_shader_ballot; |
| 217 | has_vertex_viewport_layer = GLAD_GL_ARB_shader_viewport_layer_array; | 217 | has_vertex_viewport_layer = GLAD_GL_ARB_shader_viewport_layer_array; |
| 218 | has_image_load_formatted = HasExtension(extensions, "GL_EXT_shader_image_load_formatted"); | 218 | has_image_load_formatted = HasExtension(extensions, "GL_EXT_shader_image_load_formatted"); |
| 219 | has_texture_shadow_lod = HasExtension(extensions, "GL_EXT_texture_shadow_lod"); | ||
| 219 | has_astc = IsASTCSupported(); | 220 | has_astc = IsASTCSupported(); |
| 220 | has_variable_aoffi = TestVariableAoffi(); | 221 | has_variable_aoffi = TestVariableAoffi(); |
| 221 | has_component_indexing_bug = is_amd; | 222 | has_component_indexing_bug = is_amd; |
| @@ -245,6 +246,7 @@ Device::Device(std::nullptr_t) { | |||
| 245 | has_shader_ballot = true; | 246 | has_shader_ballot = true; |
| 246 | has_vertex_viewport_layer = true; | 247 | has_vertex_viewport_layer = true; |
| 247 | has_image_load_formatted = true; | 248 | has_image_load_formatted = true; |
| 249 | has_texture_shadow_lod = true; | ||
| 248 | has_variable_aoffi = true; | 250 | has_variable_aoffi = true; |
| 249 | } | 251 | } |
| 250 | 252 | ||
diff --git a/src/video_core/renderer_opengl/gl_device.h b/src/video_core/renderer_opengl/gl_device.h index 145347943..c86e709b1 100644 --- a/src/video_core/renderer_opengl/gl_device.h +++ b/src/video_core/renderer_opengl/gl_device.h | |||
| @@ -68,6 +68,10 @@ public: | |||
| 68 | return has_image_load_formatted; | 68 | return has_image_load_formatted; |
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | bool HasTextureShadowLod() const { | ||
| 72 | return has_texture_shadow_lod; | ||
| 73 | } | ||
| 74 | |||
| 71 | bool HasASTC() const { | 75 | bool HasASTC() const { |
| 72 | return has_astc; | 76 | return has_astc; |
| 73 | } | 77 | } |
| @@ -110,6 +114,7 @@ private: | |||
| 110 | bool has_shader_ballot{}; | 114 | bool has_shader_ballot{}; |
| 111 | bool has_vertex_viewport_layer{}; | 115 | bool has_vertex_viewport_layer{}; |
| 112 | bool has_image_load_formatted{}; | 116 | bool has_image_load_formatted{}; |
| 117 | bool has_texture_shadow_lod{}; | ||
| 113 | bool has_astc{}; | 118 | bool has_astc{}; |
| 114 | bool has_variable_aoffi{}; | 119 | bool has_variable_aoffi{}; |
| 115 | bool has_component_indexing_bug{}; | 120 | bool has_component_indexing_bug{}; |
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index d6e30b321..2c49aeaac 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -37,6 +37,7 @@ using Tegra::Shader::IpaMode; | |||
| 37 | using Tegra::Shader::IpaSampleMode; | 37 | using Tegra::Shader::IpaSampleMode; |
| 38 | using Tegra::Shader::PixelImap; | 38 | using Tegra::Shader::PixelImap; |
| 39 | using Tegra::Shader::Register; | 39 | using Tegra::Shader::Register; |
| 40 | using Tegra::Shader::TextureType; | ||
| 40 | using VideoCommon::Shader::BuildTransformFeedback; | 41 | using VideoCommon::Shader::BuildTransformFeedback; |
| 41 | using VideoCommon::Shader::Registry; | 42 | using VideoCommon::Shader::Registry; |
| 42 | 43 | ||
| @@ -526,6 +527,9 @@ private: | |||
| 526 | if (device.HasImageLoadFormatted()) { | 527 | if (device.HasImageLoadFormatted()) { |
| 527 | code.AddLine("#extension GL_EXT_shader_image_load_formatted : require"); | 528 | code.AddLine("#extension GL_EXT_shader_image_load_formatted : require"); |
| 528 | } | 529 | } |
| 530 | if (device.HasTextureShadowLod()) { | ||
| 531 | code.AddLine("#extension GL_EXT_texture_shadow_lod : require"); | ||
| 532 | } | ||
| 529 | if (device.HasWarpIntrinsics()) { | 533 | if (device.HasWarpIntrinsics()) { |
| 530 | code.AddLine("#extension GL_NV_gpu_shader5 : require"); | 534 | code.AddLine("#extension GL_NV_gpu_shader5 : require"); |
| 531 | code.AddLine("#extension GL_NV_shader_thread_group : require"); | 535 | code.AddLine("#extension GL_NV_shader_thread_group : require"); |
| @@ -909,13 +913,13 @@ private: | |||
| 909 | return "samplerBuffer"; | 913 | return "samplerBuffer"; |
| 910 | } | 914 | } |
| 911 | switch (sampler.type) { | 915 | switch (sampler.type) { |
| 912 | case Tegra::Shader::TextureType::Texture1D: | 916 | case TextureType::Texture1D: |
| 913 | return "sampler1D"; | 917 | return "sampler1D"; |
| 914 | case Tegra::Shader::TextureType::Texture2D: | 918 | case TextureType::Texture2D: |
| 915 | return "sampler2D"; | 919 | return "sampler2D"; |
| 916 | case Tegra::Shader::TextureType::Texture3D: | 920 | case TextureType::Texture3D: |
| 917 | return "sampler3D"; | 921 | return "sampler3D"; |
| 918 | case Tegra::Shader::TextureType::TextureCube: | 922 | case TextureType::TextureCube: |
| 919 | return "samplerCube"; | 923 | return "samplerCube"; |
| 920 | default: | 924 | default: |
| 921 | UNREACHABLE(); | 925 | UNREACHABLE(); |
| @@ -1380,8 +1384,19 @@ private: | |||
| 1380 | const std::size_t count = operation.GetOperandsCount(); | 1384 | const std::size_t count = operation.GetOperandsCount(); |
| 1381 | const bool has_array = meta->sampler.is_array; | 1385 | const bool has_array = meta->sampler.is_array; |
| 1382 | const bool has_shadow = meta->sampler.is_shadow; | 1386 | const bool has_shadow = meta->sampler.is_shadow; |
| 1387 | const bool workaround_lod_array_shadow_as_grad = | ||
| 1388 | !device.HasTextureShadowLod() && function_suffix == "Lod" && meta->sampler.is_shadow && | ||
| 1389 | ((meta->sampler.type == TextureType::Texture2D && meta->sampler.is_array) || | ||
| 1390 | meta->sampler.type == TextureType::TextureCube); | ||
| 1391 | |||
| 1392 | std::string expr = "texture"; | ||
| 1393 | |||
| 1394 | if (workaround_lod_array_shadow_as_grad) { | ||
| 1395 | expr += "Grad"; | ||
| 1396 | } else { | ||
| 1397 | expr += function_suffix; | ||
| 1398 | } | ||
| 1383 | 1399 | ||
| 1384 | std::string expr = "texture" + function_suffix; | ||
| 1385 | if (!meta->aoffi.empty()) { | 1400 | if (!meta->aoffi.empty()) { |
| 1386 | expr += "Offset"; | 1401 | expr += "Offset"; |
| 1387 | } else if (!meta->ptp.empty()) { | 1402 | } else if (!meta->ptp.empty()) { |
| @@ -1415,6 +1430,16 @@ private: | |||
| 1415 | expr += ')'; | 1430 | expr += ')'; |
| 1416 | } | 1431 | } |
| 1417 | 1432 | ||
| 1433 | if (workaround_lod_array_shadow_as_grad) { | ||
| 1434 | switch (meta->sampler.type) { | ||
| 1435 | case TextureType::Texture2D: | ||
| 1436 | return expr + ", vec2(0.0), vec2(0.0))"; | ||
| 1437 | case TextureType::TextureCube: | ||
| 1438 | return expr + ", vec3(0.0), vec3(0.0))"; | ||
| 1439 | } | ||
| 1440 | UNREACHABLE(); | ||
| 1441 | } | ||
| 1442 | |||
| 1418 | for (const auto& variant : extras) { | 1443 | for (const auto& variant : extras) { |
| 1419 | if (const auto argument = std::get_if<TextureArgument>(&variant)) { | 1444 | if (const auto argument = std::get_if<TextureArgument>(&variant)) { |
| 1420 | expr += GenerateTextureArgument(*argument); | 1445 | expr += GenerateTextureArgument(*argument); |
| @@ -2041,8 +2066,19 @@ private: | |||
| 2041 | const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); | 2066 | const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); |
| 2042 | ASSERT(meta); | 2067 | ASSERT(meta); |
| 2043 | 2068 | ||
| 2044 | std::string expr = GenerateTexture( | 2069 | std::string expr{}; |
| 2045 | operation, "Lod", {TextureArgument{Type::Float, meta->lod}, TextureOffset{}}); | 2070 | |
| 2071 | if (!device.HasTextureShadowLod() && meta->sampler.is_shadow && | ||
| 2072 | ((meta->sampler.type == TextureType::Texture2D && meta->sampler.is_array) || | ||
| 2073 | meta->sampler.type == TextureType::TextureCube)) { | ||
| 2074 | LOG_ERROR(Render_OpenGL, | ||
| 2075 | "Device lacks GL_EXT_texture_shadow_lod, using textureGrad as a workaround"); | ||
| 2076 | expr = GenerateTexture(operation, "Lod", {}); | ||
| 2077 | } else { | ||
| 2078 | expr = GenerateTexture(operation, "Lod", | ||
| 2079 | {TextureArgument{Type::Float, meta->lod}, TextureOffset{}}); | ||
| 2080 | } | ||
| 2081 | |||
| 2046 | if (meta->sampler.is_shadow) { | 2082 | if (meta->sampler.is_shadow) { |
| 2047 | expr = "vec4(" + expr + ')'; | 2083 | expr = "vec4(" + expr + ')'; |
| 2048 | } | 2084 | } |