summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2018-08-22 00:37:30 -0400
committerGravatar GitHub2018-08-22 00:37:30 -0400
commitcb8b3715703573e268b2d93046d933eb40c04064 (patch)
treecd66725729ca58637b93db11b67a2638c88081a0 /src
parentMerge pull request #1152 from ogniK5377/plu-include (diff)
parentRevert "Shader: Use the right sampler type in the TEX, TEXS and TLDS instruct... (diff)
downloadyuzu-cb8b3715703573e268b2d93046d933eb40c04064.tar.gz
yuzu-cb8b3715703573e268b2d93046d933eb40c04064.tar.xz
yuzu-cb8b3715703573e268b2d93046d933eb40c04064.zip
Merge pull request #1151 from bunnei/revert-4a2ee191
Revert "Shader: Use the right sampler type in the TEX, TEXS and TLDS …"
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp134
-rw-r--r--src/video_core/renderer_opengl/gl_shader_gen.h50
2 files changed, 31 insertions, 153 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index aeb908744..5b976b636 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -440,12 +440,13 @@ public:
440 } 440 }
441 declarations.AddNewLine(); 441 declarations.AddNewLine();
442 442
443 const auto& samplers = GetSamplers(); 443 // Append the sampler2D array for the used textures.
444 for (const auto& sampler : samplers) { 444 size_t num_samplers = GetSamplers().size();
445 declarations.AddLine("uniform " + sampler.GetTypeString() + ' ' + sampler.GetName() + 445 if (num_samplers > 0) {
446 ';'); 446 declarations.AddLine("uniform sampler2D " + SamplerEntry::GetArrayName(stage) + '[' +
447 std::to_string(num_samplers) + "];");
448 declarations.AddNewLine();
447 } 449 }
448 declarations.AddNewLine();
449 } 450 }
450 451
451 /// Returns a list of constant buffer declarations 452 /// Returns a list of constant buffer declarations
@@ -457,14 +458,13 @@ public:
457 } 458 }
458 459
459 /// Returns a list of samplers used in the shader 460 /// Returns a list of samplers used in the shader
460 const std::vector<SamplerEntry>& GetSamplers() const { 461 std::vector<SamplerEntry> GetSamplers() const {
461 return used_samplers; 462 return used_samplers;
462 } 463 }
463 464
464 /// Returns the GLSL sampler used for the input shader sampler, and creates a new one if 465 /// Returns the GLSL sampler used for the input shader sampler, and creates a new one if
465 /// necessary. 466 /// necessary.
466 std::string AccessSampler(const Sampler& sampler, Tegra::Shader::TextureType type, 467 std::string AccessSampler(const Sampler& sampler) {
467 bool is_array) {
468 size_t offset = static_cast<size_t>(sampler.index.Value()); 468 size_t offset = static_cast<size_t>(sampler.index.Value());
469 469
470 // If this sampler has already been used, return the existing mapping. 470 // If this sampler has already been used, return the existing mapping.
@@ -473,13 +473,12 @@ public:
473 [&](const SamplerEntry& entry) { return entry.GetOffset() == offset; }); 473 [&](const SamplerEntry& entry) { return entry.GetOffset() == offset; });
474 474
475 if (itr != used_samplers.end()) { 475 if (itr != used_samplers.end()) {
476 ASSERT(itr->GetType() == type && itr->IsArray() == is_array);
477 return itr->GetName(); 476 return itr->GetName();
478 } 477 }
479 478
480 // Otherwise create a new mapping for this sampler 479 // Otherwise create a new mapping for this sampler
481 size_t next_index = used_samplers.size(); 480 size_t next_index = used_samplers.size();
482 SamplerEntry entry{stage, offset, next_index, type, is_array}; 481 SamplerEntry entry{stage, offset, next_index};
483 used_samplers.emplace_back(entry); 482 used_samplers.emplace_back(entry);
484 return entry.GetName(); 483 return entry.GetName();
485 } 484 }
@@ -657,8 +656,8 @@ private:
657 } 656 }
658 657
659 /// Generates code representing a texture sampler. 658 /// Generates code representing a texture sampler.
660 std::string GetSampler(const Sampler& sampler, Tegra::Shader::TextureType type, bool is_array) { 659 std::string GetSampler(const Sampler& sampler) {
661 return regs.AccessSampler(sampler, type, is_array); 660 return regs.AccessSampler(sampler);
662 } 661 }
663 662
664 /** 663 /**
@@ -1556,39 +1555,10 @@ private:
1556 break; 1555 break;
1557 } 1556 }
1558 case OpCode::Id::TEX: { 1557 case OpCode::Id::TEX: {
1559 ASSERT_MSG(instr.tex.array == 0, "TEX arrays unimplemented"); 1558 const std::string op_a = regs.GetRegisterAsFloat(instr.gpr8);
1560 std::string coord{}; 1559 const std::string op_b = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
1561 1560 const std::string sampler = GetSampler(instr.sampler);
1562 switch (instr.tex.texture_type) { 1561 const std::string coord = "vec2 coords = vec2(" + op_a + ", " + op_b + ");";
1563 case Tegra::Shader::TextureType::Texture2D: {
1564 std::string x = regs.GetRegisterAsFloat(instr.gpr8);
1565 std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
1566 coord = "vec2 coords = vec2(" + x + ", " + y + ");";
1567 break;
1568 }
1569 case Tegra::Shader::TextureType::Texture3D: {
1570 std::string x = regs.GetRegisterAsFloat(instr.gpr8);
1571 std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
1572 std::string z = regs.GetRegisterAsFloat(instr.gpr20);
1573 coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");";
1574 break;
1575 }
1576 case Tegra::Shader::TextureType::TextureCube: {
1577 std::string x = regs.GetRegisterAsFloat(instr.gpr8);
1578 std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
1579 std::string z = regs.GetRegisterAsFloat(instr.gpr8.Value() + 2);
1580 ASSERT(instr.gpr20.Value() == Register::ZeroIndex);
1581 coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");";
1582 break;
1583 }
1584 default:
1585 LOG_CRITICAL(HW_GPU, "Unhandled texture type {}",
1586 static_cast<u32>(instr.tex.texture_type.Value()));
1587 UNREACHABLE();
1588 }
1589
1590 const std::string sampler =
1591 GetSampler(instr.sampler, instr.tex.texture_type, instr.tex.array);
1592 // Add an extra scope and declare the texture coords inside to prevent 1562 // Add an extra scope and declare the texture coords inside to prevent
1593 // overwriting them in case they are used as outputs of the texs instruction. 1563 // overwriting them in case they are used as outputs of the texs instruction.
1594 shader.AddLine("{"); 1564 shader.AddLine("{");
@@ -1610,72 +1580,20 @@ private:
1610 break; 1580 break;
1611 } 1581 }
1612 case OpCode::Id::TEXS: { 1582 case OpCode::Id::TEXS: {
1613 std::string coord{}; 1583 const std::string op_a = regs.GetRegisterAsFloat(instr.gpr8);
1614 1584 const std::string op_b = regs.GetRegisterAsFloat(instr.gpr20);
1615 switch (instr.texs.GetTextureType()) { 1585 const std::string sampler = GetSampler(instr.sampler);
1616 case Tegra::Shader::TextureType::Texture2D: { 1586 const std::string coord = "vec2 coords = vec2(" + op_a + ", " + op_b + ");";
1617 if (instr.texs.IsArrayTexture()) {
1618 std::string index = regs.GetRegisterAsInteger(instr.gpr8);
1619 std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
1620 std::string y = regs.GetRegisterAsFloat(instr.gpr20);
1621 coord = "vec3 coords = vec3(" + x + ", " + y + ", " + index + ");";
1622 } else {
1623 std::string x = regs.GetRegisterAsFloat(instr.gpr8);
1624 std::string y = regs.GetRegisterAsFloat(instr.gpr20);
1625 coord = "vec2 coords = vec2(" + x + ", " + y + ");";
1626 }
1627 break;
1628 }
1629 case Tegra::Shader::TextureType::Texture3D: {
1630 std::string x = regs.GetRegisterAsFloat(instr.gpr8);
1631 std::string y = regs.GetRegisterAsFloat(instr.gpr20);
1632 std::string z = regs.GetRegisterAsFloat(instr.gpr20.Value() + 1);
1633 coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");";
1634 break;
1635 }
1636 case Tegra::Shader::TextureType::TextureCube: {
1637 std::string x = regs.GetRegisterAsFloat(instr.gpr8);
1638 std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
1639 std::string z = regs.GetRegisterAsFloat(instr.gpr20);
1640 coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");";
1641 break;
1642 }
1643 default:
1644 LOG_CRITICAL(HW_GPU, "Unhandled texture type {}",
1645 static_cast<u32>(instr.texs.GetTextureType()));
1646 UNREACHABLE();
1647 }
1648 const std::string sampler = GetSampler(instr.sampler, instr.texs.GetTextureType(),
1649 instr.texs.IsArrayTexture());
1650 1587
1651 const std::string texture = "texture(" + sampler + ", coords)"; 1588 const std::string texture = "texture(" + sampler + ", coords)";
1652 WriteTexsInstruction(instr, coord, texture); 1589 WriteTexsInstruction(instr, coord, texture);
1653 break; 1590 break;
1654 } 1591 }
1655 case OpCode::Id::TLDS: { 1592 case OpCode::Id::TLDS: {
1656 ASSERT(instr.tlds.GetTextureType() == Tegra::Shader::TextureType::Texture2D); 1593 const std::string op_a = regs.GetRegisterAsInteger(instr.gpr8);
1657 ASSERT(instr.tlds.IsArrayTexture() == false); 1594 const std::string op_b = regs.GetRegisterAsInteger(instr.gpr20);
1658 std::string coord{}; 1595 const std::string sampler = GetSampler(instr.sampler);
1659 1596 const std::string coord = "ivec2 coords = ivec2(" + op_a + ", " + op_b + ");";
1660 switch (instr.tlds.GetTextureType()) {
1661 case Tegra::Shader::TextureType::Texture2D: {
1662 if (instr.tlds.IsArrayTexture()) {
1663 LOG_CRITICAL(HW_GPU, "Unhandled 2d array texture");
1664 UNREACHABLE();
1665 } else {
1666 std::string x = regs.GetRegisterAsInteger(instr.gpr8);
1667 std::string y = regs.GetRegisterAsInteger(instr.gpr20);
1668 coord = "ivec2 coords = ivec2(" + x + ", " + y + ");";
1669 }
1670 break;
1671 }
1672 default:
1673 LOG_CRITICAL(HW_GPU, "Unhandled texture type {}",
1674 static_cast<u32>(instr.tlds.GetTextureType()));
1675 UNREACHABLE();
1676 }
1677 const std::string sampler = GetSampler(instr.sampler, instr.tlds.GetTextureType(),
1678 instr.tlds.IsArrayTexture());
1679 const std::string texture = "texelFetch(" + sampler + ", coords, 0)"; 1597 const std::string texture = "texelFetch(" + sampler + ", coords, 0)";
1680 WriteTexsInstruction(instr, coord, texture); 1598 WriteTexsInstruction(instr, coord, texture);
1681 break; 1599 break;
@@ -1698,8 +1616,7 @@ private:
1698 UNREACHABLE(); 1616 UNREACHABLE();
1699 } 1617 }
1700 1618
1701 const std::string sampler = 1619 const std::string sampler = GetSampler(instr.sampler);
1702 GetSampler(instr.sampler, instr.tld4.texture_type, instr.tld4.array);
1703 // Add an extra scope and declare the texture coords inside to prevent 1620 // Add an extra scope and declare the texture coords inside to prevent
1704 // overwriting them in case they are used as outputs of the texs instruction. 1621 // overwriting them in case they are used as outputs of the texs instruction.
1705 shader.AddLine("{"); 1622 shader.AddLine("{");
@@ -1725,8 +1642,7 @@ private:
1725 const std::string op_a = regs.GetRegisterAsFloat(instr.gpr8); 1642 const std::string op_a = regs.GetRegisterAsFloat(instr.gpr8);
1726 const std::string op_b = regs.GetRegisterAsFloat(instr.gpr20); 1643 const std::string op_b = regs.GetRegisterAsFloat(instr.gpr20);
1727 // TODO(Subv): Figure out how the sampler type is encoded in the TLD4S instruction. 1644 // TODO(Subv): Figure out how the sampler type is encoded in the TLD4S instruction.
1728 const std::string sampler = 1645 const std::string sampler = GetSampler(instr.sampler);
1729 GetSampler(instr.sampler, Tegra::Shader::TextureType::Texture2D, false);
1730 const std::string coord = "vec2 coords = vec2(" + op_a + ", " + op_b + ");"; 1646 const std::string coord = "vec2 coords = vec2(" + op_a + ", " + op_b + ");";
1731 const std::string texture = "textureGather(" + sampler + ", coords, " + 1647 const std::string texture = "textureGather(" + sampler + ", coords, " +
1732 std::to_string(instr.tld4s.component) + ')'; 1648 std::to_string(instr.tld4s.component) + ')';
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.h b/src/video_core/renderer_opengl/gl_shader_gen.h
index db48da645..4729ce0fc 100644
--- a/src/video_core/renderer_opengl/gl_shader_gen.h
+++ b/src/video_core/renderer_opengl/gl_shader_gen.h
@@ -11,7 +11,6 @@
11#include <vector> 11#include <vector>
12#include "common/common_types.h" 12#include "common/common_types.h"
13#include "common/hash.h" 13#include "common/hash.h"
14#include "video_core/engines/shader_bytecode.h"
15 14
16namespace GLShader { 15namespace GLShader {
17 16
@@ -73,9 +72,8 @@ class SamplerEntry {
73 using Maxwell = Tegra::Engines::Maxwell3D::Regs; 72 using Maxwell = Tegra::Engines::Maxwell3D::Regs;
74 73
75public: 74public:
76 SamplerEntry(Maxwell::ShaderStage stage, size_t offset, size_t index, 75 SamplerEntry(Maxwell::ShaderStage stage, size_t offset, size_t index)
77 Tegra::Shader::TextureType type, bool is_array) 76 : offset(offset), stage(stage), sampler_index(index) {}
78 : offset(offset), stage(stage), sampler_index(index), type(type), is_array(is_array) {}
79 77
80 size_t GetOffset() const { 78 size_t GetOffset() const {
81 return offset; 79 return offset;
@@ -90,41 +88,8 @@ public:
90 } 88 }
91 89
92 std::string GetName() const { 90 std::string GetName() const {
93 return std::string(TextureSamplerNames[static_cast<size_t>(stage)]) + '_' + 91 return std::string(TextureSamplerNames[static_cast<size_t>(stage)]) + '[' +
94 std::to_string(sampler_index); 92 std::to_string(sampler_index) + ']';
95 }
96
97 std::string GetTypeString() const {
98 using Tegra::Shader::TextureType;
99 std::string glsl_type;
100
101 switch (type) {
102 case TextureType::Texture1D:
103 glsl_type = "sampler1D";
104 break;
105 case TextureType::Texture2D:
106 glsl_type = "sampler2D";
107 break;
108 case TextureType::Texture3D:
109 glsl_type = "sampler3D";
110 break;
111 case TextureType::TextureCube:
112 glsl_type = "samplerCube";
113 break;
114 default:
115 UNIMPLEMENTED();
116 }
117 if (is_array)
118 glsl_type += "Array";
119 return glsl_type;
120 }
121
122 Tegra::Shader::TextureType GetType() const {
123 return type;
124 }
125
126 bool IsArray() const {
127 return is_array;
128 } 93 }
129 94
130 static std::string GetArrayName(Maxwell::ShaderStage stage) { 95 static std::string GetArrayName(Maxwell::ShaderStage stage) {
@@ -135,14 +100,11 @@ private:
135 static constexpr std::array<const char*, Maxwell::MaxShaderStage> TextureSamplerNames = { 100 static constexpr std::array<const char*, Maxwell::MaxShaderStage> TextureSamplerNames = {
136 "tex_vs", "tex_tessc", "tex_tesse", "tex_gs", "tex_fs", 101 "tex_vs", "tex_tessc", "tex_tesse", "tex_gs", "tex_fs",
137 }; 102 };
138
139 /// Offset in TSC memory from which to read the sampler object, as specified by the sampling 103 /// Offset in TSC memory from which to read the sampler object, as specified by the sampling
140 /// instruction. 104 /// instruction.
141 size_t offset; 105 size_t offset;
142 Maxwell::ShaderStage stage; ///< Shader stage where this sampler was used. 106 Maxwell::ShaderStage stage; ///< Shader stage where this sampler was used.
143 size_t sampler_index; ///< Value used to index into the generated GLSL sampler array. 107 size_t sampler_index; ///< Value used to index into the generated GLSL sampler array.
144 Tegra::Shader::TextureType type; ///< The type used to sample this texture (Texture2D, etc)
145 bool is_array; ///< Whether the texture is being sampled as an array texture or not.
146}; 108};
147 109
148struct ShaderEntries { 110struct ShaderEntries {