summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp42
1 files changed, 38 insertions, 4 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 7dc2e0560..ece386cdc 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -453,9 +453,13 @@ private:
453 void DeclareSamplers() { 453 void DeclareSamplers() {
454 const auto& samplers = ir.GetSamplers(); 454 const auto& samplers = ir.GetSamplers();
455 for (const auto& sampler : samplers) { 455 for (const auto& sampler : samplers) {
456 std::string sampler_type = [&sampler] { 456 const std::string name{GetSampler(sampler)};
457 const std::string description{"layout (binding = SAMPLER_BINDING_" +
458 std::to_string(sampler.GetIndex()) + ") uniform "};
459 std::string sampler_type = [&]() {
457 switch (sampler.GetType()) { 460 switch (sampler.GetType()) {
458 case Tegra::Shader::TextureType::Texture1D: 461 case Tegra::Shader::TextureType::Texture1D:
462 // Special cased, read below.
459 return "sampler1D"; 463 return "sampler1D";
460 case Tegra::Shader::TextureType::Texture2D: 464 case Tegra::Shader::TextureType::Texture2D:
461 return "sampler2D"; 465 return "sampler2D";
@@ -475,8 +479,19 @@ private:
475 sampler_type += "Shadow"; 479 sampler_type += "Shadow";
476 } 480 }
477 481
478 code.AddLine("layout (binding = SAMPLER_BINDING_{}) uniform {} {};", sampler.GetIndex(), 482 if (sampler.GetType() == Tegra::Shader::TextureType::Texture1D) {
479 sampler_type, GetSampler(sampler)); 483 // 1D textures can be aliased to texture buffers, hide the declarations behind a
484 // preprocessor flag and use one or the other from the GPU state. This has to be
485 // done because shaders don't have enough information to determine the texture type.
486 EmitIfdefIsBuffer(sampler);
487 code.AddLine(description + "samplerBuffer " + name + ';');
488 code.AddLine("#else");
489 code.AddLine(description + sampler_type + ' ' + name + ';');
490 code.AddLine("#endif");
491 } else {
492 // The other texture types (2D, 3D and cubes) don't have this issue.
493 code.AddLine(description + sampler_type + ' ' + name + ';');
494 }
480 } 495 }
481 if (!samplers.empty()) { 496 if (!samplers.empty()) {
482 code.AddNewLine(); 497 code.AddNewLine();
@@ -1439,13 +1454,28 @@ private:
1439 else if (next < count) 1454 else if (next < count)
1440 expr += ", "; 1455 expr += ", ";
1441 } 1456 }
1457
1458 // Store a copy of the expression without the lod to be used with texture buffers
1459 std::string expr_buffer = expr;
1460
1442 if (meta->lod) { 1461 if (meta->lod) {
1443 expr += ", "; 1462 expr += ", ";
1444 expr += CastOperand(Visit(meta->lod), Type::Int); 1463 expr += CastOperand(Visit(meta->lod), Type::Int);
1445 } 1464 }
1446 expr += ')'; 1465 expr += ')';
1466 expr += GetSwizzle(meta->element);
1447 1467
1448 return expr + GetSwizzle(meta->element); 1468 expr_buffer += ')';
1469 expr_buffer += GetSwizzle(meta->element);
1470
1471 const std::string tmp{code.GenerateTemporary()};
1472 EmitIfdefIsBuffer(meta->sampler);
1473 code.AddLine("float " + tmp + " = " + expr_buffer + ';');
1474 code.AddLine("#else");
1475 code.AddLine("float " + tmp + " = " + expr + ';');
1476 code.AddLine("#endif");
1477
1478 return tmp;
1449 } 1479 }
1450 1480
1451 std::string Branch(Operation operation) { 1481 std::string Branch(Operation operation) {
@@ -1756,6 +1786,10 @@ private:
1756 return GetDeclarationWithSuffix(static_cast<u32>(sampler.GetIndex()), "sampler"); 1786 return GetDeclarationWithSuffix(static_cast<u32>(sampler.GetIndex()), "sampler");
1757 } 1787 }
1758 1788
1789 void EmitIfdefIsBuffer(const Sampler& sampler) {
1790 code.AddLine(fmt::format("#ifdef SAMPLER_{}_IS_BUFFER", sampler.GetIndex()));
1791 }
1792
1759 std::string GetDeclarationWithSuffix(u32 index, const std::string& name) const { 1793 std::string GetDeclarationWithSuffix(u32 index, const std::string& name) const {
1760 return fmt::format("{}_{}_{}", name, index, suffix); 1794 return fmt::format("{}_{}_{}", name, index, suffix);
1761 } 1795 }