diff options
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 50 |
1 files changed, 43 insertions, 7 deletions
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 | } |