summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp50
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;
37using Tegra::Shader::IpaSampleMode; 37using Tegra::Shader::IpaSampleMode;
38using Tegra::Shader::PixelImap; 38using Tegra::Shader::PixelImap;
39using Tegra::Shader::Register; 39using Tegra::Shader::Register;
40using Tegra::Shader::TextureType;
40using VideoCommon::Shader::BuildTransformFeedback; 41using VideoCommon::Shader::BuildTransformFeedback;
41using VideoCommon::Shader::Registry; 42using 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 }