summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2020-10-28 17:11:24 -0300
committerGravatar ReinUsesLisp2020-10-28 17:12:40 -0300
commit657771bdcbe2a35277e8d7e453b00ab21a7f27f0 (patch)
treeae080c557fc103ca156262752c3e711950a18778 /src
parentMerge pull request #4851 from ReinUsesLisp/core-threads-race (diff)
downloadyuzu-657771bdcbe2a35277e8d7e453b00ab21a7f27f0.tar.gz
yuzu-657771bdcbe2a35277e8d7e453b00ab21a7f27f0.tar.xz
yuzu-657771bdcbe2a35277e8d7e453b00ab21a7f27f0.zip
shader: Partially implement texture cube array shadow
This implements texture cube arrays with shadow comparisons but doesn't fix the asserts related to it. Fixes out of bounds reads on swizzle constructors and makes them use bounds checked ::at instead of the unsafe operator[].
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_arb_decompiler.cpp41
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp20
-rw-r--r--src/video_core/shader/decode/texture.cpp1
3 files changed, 37 insertions, 25 deletions
diff --git a/src/video_core/renderer_opengl/gl_arb_decompiler.cpp b/src/video_core/renderer_opengl/gl_arb_decompiler.cpp
index f4db62787..d6120c23e 100644
--- a/src/video_core/renderer_opengl/gl_arb_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_arb_decompiler.cpp
@@ -39,8 +39,8 @@ using Operation = const OperationNode&;
39constexpr std::array INTERNAL_FLAG_NAMES = {"ZERO", "SIGN", "CARRY", "OVERFLOW"}; 39constexpr std::array INTERNAL_FLAG_NAMES = {"ZERO", "SIGN", "CARRY", "OVERFLOW"};
40 40
41char Swizzle(std::size_t component) { 41char Swizzle(std::size_t component) {
42 ASSERT(component < 4); 42 static constexpr std::string_view SWIZZLE{"xyzw"};
43 return component["xyzw"]; 43 return SWIZZLE.at(component);
44} 44}
45 45
46constexpr bool IsGenericAttribute(Attribute::Index index) { 46constexpr bool IsGenericAttribute(Attribute::Index index) {
@@ -224,7 +224,7 @@ private:
224 224
225 std::string Visit(const Node& node); 225 std::string Visit(const Node& node);
226 226
227 std::pair<std::string, std::size_t> BuildCoords(Operation); 227 std::tuple<std::string, std::string, std::size_t> BuildCoords(Operation);
228 std::string BuildAoffi(Operation); 228 std::string BuildAoffi(Operation);
229 std::string GlobalMemoryPointer(const GmemNode& gmem); 229 std::string GlobalMemoryPointer(const GmemNode& gmem);
230 void Exit(); 230 void Exit();
@@ -1416,12 +1416,12 @@ std::string ARBDecompiler::Visit(const Node& node) {
1416 return {}; 1416 return {};
1417} 1417}
1418 1418
1419std::pair<std::string, std::size_t> ARBDecompiler::BuildCoords(Operation operation) { 1419std::tuple<std::string, std::string, std::size_t> ARBDecompiler::BuildCoords(Operation operation) {
1420 const auto& meta = std::get<MetaTexture>(operation.GetMeta()); 1420 const auto& meta = std::get<MetaTexture>(operation.GetMeta());
1421 UNIMPLEMENTED_IF(meta.sampler.is_indexed); 1421 UNIMPLEMENTED_IF(meta.sampler.is_indexed);
1422 UNIMPLEMENTED_IF(meta.sampler.is_shadow && meta.sampler.is_array &&
1423 meta.sampler.type == Tegra::Shader::TextureType::TextureCube);
1424 1422
1423 const bool is_extended = meta.sampler.is_shadow && meta.sampler.is_array &&
1424 meta.sampler.type == Tegra::Shader::TextureType::TextureCube;
1425 const std::size_t count = operation.GetOperandsCount(); 1425 const std::size_t count = operation.GetOperandsCount();
1426 std::string temporary = AllocVectorTemporary(); 1426 std::string temporary = AllocVectorTemporary();
1427 std::size_t i = 0; 1427 std::size_t i = 0;
@@ -1429,12 +1429,21 @@ std::pair<std::string, std::size_t> ARBDecompiler::BuildCoords(Operation operati
1429 AddLine("MOV.F {}.{}, {};", temporary, Swizzle(i), Visit(operation[i])); 1429 AddLine("MOV.F {}.{}, {};", temporary, Swizzle(i), Visit(operation[i]));
1430 } 1430 }
1431 if (meta.sampler.is_array) { 1431 if (meta.sampler.is_array) {
1432 AddLine("I2F.S {}.{}, {};", temporary, Swizzle(i++), Visit(meta.array)); 1432 AddLine("I2F.S {}.{}, {};", temporary, Swizzle(i), Visit(meta.array));
1433 ++i;
1433 } 1434 }
1434 if (meta.sampler.is_shadow) { 1435 if (meta.sampler.is_shadow) {
1435 AddLine("MOV.F {}.{}, {};", temporary, Swizzle(i++), Visit(meta.depth_compare)); 1436 std::string compare = Visit(meta.depth_compare);
1437 if (is_extended) {
1438 ASSERT(i == 4);
1439 std::string extra_coord = AllocVectorTemporary();
1440 AddLine("MOV.F {}.x, {};", extra_coord, compare);
1441 return {fmt::format("{}, {}", temporary, extra_coord), extra_coord, 0};
1442 }
1443 AddLine("MOV.F {}.{}, {};", temporary, Swizzle(i), compare);
1444 ++i;
1436 } 1445 }
1437 return {std::move(temporary), i}; 1446 return {temporary, temporary, i};
1438} 1447}
1439 1448
1440std::string ARBDecompiler::BuildAoffi(Operation operation) { 1449std::string ARBDecompiler::BuildAoffi(Operation operation) {
@@ -1859,7 +1868,7 @@ std::string ARBDecompiler::LogicalAddCarry(Operation operation) {
1859std::string ARBDecompiler::Texture(Operation operation) { 1868std::string ARBDecompiler::Texture(Operation operation) {
1860 const auto& meta = std::get<MetaTexture>(operation.GetMeta()); 1869 const auto& meta = std::get<MetaTexture>(operation.GetMeta());
1861 const u32 sampler_id = device.GetBaseBindings(stage).sampler + meta.sampler.index; 1870 const u32 sampler_id = device.GetBaseBindings(stage).sampler + meta.sampler.index;
1862 const auto [temporary, swizzle] = BuildCoords(operation); 1871 const auto [coords, temporary, swizzle] = BuildCoords(operation);
1863 1872
1864 std::string_view opcode = "TEX"; 1873 std::string_view opcode = "TEX";
1865 std::string extra; 1874 std::string extra;
@@ -1888,7 +1897,7 @@ std::string ARBDecompiler::Texture(Operation operation) {
1888 } 1897 }
1889 } 1898 }
1890 1899
1891 AddLine("{}.F {}, {},{} texture[{}], {}{};", opcode, temporary, temporary, extra, sampler_id, 1900 AddLine("{}.F {}, {},{} texture[{}], {}{};", opcode, temporary, coords, extra, sampler_id,
1892 TextureType(meta), BuildAoffi(operation)); 1901 TextureType(meta), BuildAoffi(operation));
1893 AddLine("MOV.U {}.x, {}.{};", temporary, temporary, Swizzle(meta.element)); 1902 AddLine("MOV.U {}.x, {}.{};", temporary, temporary, Swizzle(meta.element));
1894 return fmt::format("{}.x", temporary); 1903 return fmt::format("{}.x", temporary);
@@ -1897,7 +1906,7 @@ std::string ARBDecompiler::Texture(Operation operation) {
1897std::string ARBDecompiler::TextureGather(Operation operation) { 1906std::string ARBDecompiler::TextureGather(Operation operation) {
1898 const auto& meta = std::get<MetaTexture>(operation.GetMeta()); 1907 const auto& meta = std::get<MetaTexture>(operation.GetMeta());
1899 const u32 sampler_id = device.GetBaseBindings(stage).sampler + meta.sampler.index; 1908 const u32 sampler_id = device.GetBaseBindings(stage).sampler + meta.sampler.index;
1900 const auto [temporary, swizzle] = BuildCoords(operation); 1909 const auto [coords, temporary, swizzle] = BuildCoords(operation);
1901 1910
1902 std::string comp; 1911 std::string comp;
1903 if (!meta.sampler.is_shadow) { 1912 if (!meta.sampler.is_shadow) {
@@ -1907,7 +1916,7 @@ std::string ARBDecompiler::TextureGather(Operation operation) {
1907 1916
1908 AddLine("TXG.F {}, {}, texture[{}]{}, {}{};", temporary, temporary, sampler_id, comp, 1917 AddLine("TXG.F {}, {}, texture[{}]{}, {}{};", temporary, temporary, sampler_id, comp,
1909 TextureType(meta), BuildAoffi(operation)); 1918 TextureType(meta), BuildAoffi(operation));
1910 AddLine("MOV.U {}.x, {}.{};", temporary, temporary, Swizzle(meta.element)); 1919 AddLine("MOV.U {}.x, {}.{};", temporary, coords, Swizzle(meta.element));
1911 return fmt::format("{}.x", temporary); 1920 return fmt::format("{}.x", temporary);
1912} 1921}
1913 1922
@@ -1945,13 +1954,13 @@ std::string ARBDecompiler::TextureQueryLod(Operation operation) {
1945std::string ARBDecompiler::TexelFetch(Operation operation) { 1954std::string ARBDecompiler::TexelFetch(Operation operation) {
1946 const auto& meta = std::get<MetaTexture>(operation.GetMeta()); 1955 const auto& meta = std::get<MetaTexture>(operation.GetMeta());
1947 const u32 sampler_id = device.GetBaseBindings(stage).sampler + meta.sampler.index; 1956 const u32 sampler_id = device.GetBaseBindings(stage).sampler + meta.sampler.index;
1948 const auto [temporary, swizzle] = BuildCoords(operation); 1957 const auto [coords, temporary, swizzle] = BuildCoords(operation);
1949 1958
1950 if (!meta.sampler.is_buffer) { 1959 if (!meta.sampler.is_buffer) {
1951 ASSERT(swizzle < 4); 1960 ASSERT(swizzle < 4);
1952 AddLine("MOV.F {}.w, {};", temporary, Visit(meta.lod)); 1961 AddLine("MOV.F {}.w, {};", temporary, Visit(meta.lod));
1953 } 1962 }
1954 AddLine("TXF.F {}, {}, texture[{}], {}{};", temporary, temporary, sampler_id, TextureType(meta), 1963 AddLine("TXF.F {}, {}, texture[{}], {}{};", temporary, coords, sampler_id, TextureType(meta),
1955 BuildAoffi(operation)); 1964 BuildAoffi(operation));
1956 AddLine("MOV.U {}.x, {}.{};", temporary, temporary, Swizzle(meta.element)); 1965 AddLine("MOV.U {}.x, {}.{};", temporary, temporary, Swizzle(meta.element));
1957 return fmt::format("{}.x", temporary); 1966 return fmt::format("{}.x", temporary);
@@ -1962,7 +1971,7 @@ std::string ARBDecompiler::TextureGradient(Operation operation) {
1962 const u32 sampler_id = device.GetBaseBindings(stage).sampler + meta.sampler.index; 1971 const u32 sampler_id = device.GetBaseBindings(stage).sampler + meta.sampler.index;
1963 const std::string ddx = AllocVectorTemporary(); 1972 const std::string ddx = AllocVectorTemporary();
1964 const std::string ddy = AllocVectorTemporary(); 1973 const std::string ddy = AllocVectorTemporary();
1965 const std::string coord = BuildCoords(operation).first; 1974 const std::string coord = std::get<1>(BuildCoords(operation));
1966 1975
1967 const std::size_t num_components = meta.derivates.size() / 2; 1976 const std::size_t num_components = meta.derivates.size() / 2;
1968 for (std::size_t index = 0; index < num_components; ++index) { 1977 for (std::size_t index = 0; index < num_components; ++index) {
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index bbb8fb095..95ca96c8e 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -2056,15 +2056,19 @@ private:
2056 } 2056 }
2057 2057
2058 Expression Texture(Operation operation) { 2058 Expression Texture(Operation operation) {
2059 const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); 2059 const auto meta = std::get<MetaTexture>(operation.GetMeta());
2060 ASSERT(meta); 2060 const bool separate_dc = meta.sampler.type == TextureType::TextureCube &&
2061 2061 meta.sampler.is_array && meta.sampler.is_shadow;
2062 std::string expr = GenerateTexture( 2062 // TODO: Replace this with an array and make GenerateTexture use C++20 std::span
2063 operation, "", {TextureOffset{}, TextureArgument{Type::Float, meta->bias}}); 2063 const std::vector<TextureIR> extras{
2064 if (meta->sampler.is_shadow) { 2064 TextureOffset{},
2065 expr = "vec4(" + expr + ')'; 2065 TextureArgument{Type::Float, meta.bias},
2066 };
2067 std::string expr = GenerateTexture(operation, "", extras, separate_dc);
2068 if (meta.sampler.is_shadow) {
2069 expr = fmt::format("vec4({})", expr);
2066 } 2070 }
2067 return {expr + GetSwizzle(meta->element), Type::Float}; 2071 return {expr + GetSwizzle(meta.element), Type::Float};
2068 } 2072 }
2069 2073
2070 Expression TextureLod(Operation operation) { 2074 Expression TextureLod(Operation operation) {
diff --git a/src/video_core/shader/decode/texture.cpp b/src/video_core/shader/decode/texture.cpp
index 4e932a4b6..02fdccd86 100644
--- a/src/video_core/shader/decode/texture.cpp
+++ b/src/video_core/shader/decode/texture.cpp
@@ -556,7 +556,6 @@ Node4 ShaderIR::GetTextureCode(Instruction instr, TextureType texture_type,
556 const bool is_shadow = depth_compare != nullptr; 556 const bool is_shadow = depth_compare != nullptr;
557 const bool is_bindless = bindless_reg.has_value(); 557 const bool is_bindless = bindless_reg.has_value();
558 558
559 UNIMPLEMENTED_IF(texture_type == TextureType::TextureCube && is_array && is_shadow);
560 ASSERT_MSG(texture_type != TextureType::Texture3D || !is_array || !is_shadow, 559 ASSERT_MSG(texture_type != TextureType::Texture3D || !is_array || !is_shadow,
561 "Illegal texture type"); 560 "Illegal texture type");
562 561