diff options
| author | 2018-08-22 00:37:30 -0400 | |
|---|---|---|
| committer | 2018-08-22 00:37:30 -0400 | |
| commit | cb8b3715703573e268b2d93046d933eb40c04064 (patch) | |
| tree | cd66725729ca58637b93db11b67a2638c88081a0 /src | |
| parent | Merge pull request #1152 from ogniK5377/plu-include (diff) | |
| parent | Revert "Shader: Use the right sampler type in the TEX, TEXS and TLDS instruct... (diff) | |
| download | yuzu-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.cpp | 134 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_gen.h | 50 |
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 | ||
| 16 | namespace GLShader { | 15 | namespace 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 | ||
| 75 | public: | 74 | public: |
| 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 | ||
| 148 | struct ShaderEntries { | 110 | struct ShaderEntries { |