From 6d235b8631697b81b08ee6f10f2fc79dc2956a50 Mon Sep 17 00:00:00 2001 From: Nguyen Dac Nam Date: Mon, 9 Mar 2020 19:33:26 +0700 Subject: shader: implement SULD.D bits32 --- src/video_core/shader/decode/image.cpp | 38 ++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 11 deletions(-) (limited to 'src/video_core/shader/decode') diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index d2fe4ec5d..02bfef524 100644 --- a/src/video_core/shader/decode/image.cpp +++ b/src/video_core/shader/decode/image.cpp @@ -53,7 +53,6 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { switch (opcode->get().GetId()) { case OpCode::Id::SULD: { - UNIMPLEMENTED_IF(instr.suldst.mode != Tegra::Shader::SurfaceDataMode::P); UNIMPLEMENTED_IF(instr.suldst.out_of_bounds_store != Tegra::Shader::OutOfBoundsStore::Ignore); @@ -62,17 +61,34 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { : GetBindlessImage(instr.gpr39, type)}; image.MarkRead(); - u32 indexer = 0; - for (u32 element = 0; element < 4; ++element) { - if (!instr.suldst.IsComponentEnabled(element)) { - continue; + if (instr.suldst.mode == Tegra::Shader::SurfaceDataMode::P) { + u32 indexer = 0; + for (u32 element = 0; element < 4; ++element) { + if (!instr.suldst.IsComponentEnabled(element)) { + continue; + } + MetaImage meta{image, {}, element}; + Node value = Operation(OperationCode::ImageLoad, meta, GetCoordinates(type)); + SetTemporary(bb, indexer++, std::move(value)); + } + for (u32 i = 0; i < indexer; ++i) { + SetRegister(bb, instr.gpr0.Value() + i, GetTemporary(i)); + } + } else if (instr.suldst.mode == Tegra::Shader::SurfaceDataMode::D_BA) { + UNIMPLEMENTED_IF(instr.suldst.GetStoreDataLayout() != StoreType::Bits32); + + switch (instr.suldst.GetStoreDataLayout()) { + case StoreType::Bits32: { + MetaImage meta{image, {}, {}}; + Node value = Operation(OperationCode::ImageLoad, meta, GetCoordinates(type)); + SetTemporary(bb, 0, std::move(value)); + SetRegister(bb, instr.gpr0.Value(), GetTemporary(0)); + break; + } + default: + UNREACHABLE(); + break; } - MetaImage meta{image, {}, element}; - Node value = Operation(OperationCode::ImageLoad, meta, GetCoordinates(type)); - SetTemporary(bb, indexer++, std::move(value)); - } - for (u32 i = 0; i < indexer; ++i) { - SetRegister(bb, instr.gpr0.Value() + i, GetTemporary(i)); } break; } -- cgit v1.2.3 From ed1d8beb1318391ca4d4a305fdd37d85c7ecd1b1 Mon Sep 17 00:00:00 2001 From: Nguyen Dac Nam Date: Mon, 9 Mar 2020 20:13:25 +0700 Subject: shader: SULD.D import StoreType --- src/video_core/shader/decode/image.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/video_core/shader/decode') diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index 02bfef524..ae41e1149 100644 --- a/src/video_core/shader/decode/image.cpp +++ b/src/video_core/shader/decode/image.cpp @@ -18,6 +18,7 @@ namespace VideoCommon::Shader { using Tegra::Shader::Instruction; using Tegra::Shader::OpCode; +using Tegra::Shader::StoreType; namespace { std::size_t GetImageTypeNumCoordinates(Tegra::Shader::ImageType image_type) { -- cgit v1.2.3 From 08db60392da9eb82fba39f99c1e650085a7d094b Mon Sep 17 00:00:00 2001 From: Nguyen Dac Nam Date: Wed, 11 Mar 2020 18:15:31 +0700 Subject: shader: SULD.D bits32 implement more complexer method. --- src/video_core/shader/decode/image.cpp | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) (limited to 'src/video_core/shader/decode') diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index ae41e1149..077bad037 100644 --- a/src/video_core/shader/decode/image.cpp +++ b/src/video_core/shader/decode/image.cpp @@ -80,10 +80,34 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { switch (instr.suldst.GetStoreDataLayout()) { case StoreType::Bits32: { - MetaImage meta{image, {}, {}}; - Node value = Operation(OperationCode::ImageLoad, meta, GetCoordinates(type)); - SetTemporary(bb, 0, std::move(value)); - SetRegister(bb, instr.gpr0.Value(), GetTemporary(0)); + Node value{}; + for (s32 i = 3; i >= 0; i--) { + MetaImage meta{image, {}, i}; + Node element_value = + Operation(OperationCode::ImageLoad, meta, GetCoordinates(type)); + + const Node comp = GetPredicateComparisonFloat(PredCondition::GreaterEqual, + element_value, Immediate(1.0f)); + const Node mul = + Operation(OperationCode::Select, comp, Immediate(1.f), Immediate(255.f)); + + Node element = Operation(OperationCode::FMul, NO_PRECISE, element_value, mul); + element = SignedOperation(OperationCode::ICastFloat, true, NO_PRECISE, + std::move(element)); + element = Operation(OperationCode::ULogicalShiftLeft, std::move(element), + Immediate(8 * i)); + if (i == 3) { + //(namkazt) for now i'm force it to 0 at alpha component if color is in + // range (0-255) + value = Operation(OperationCode::Select, comp, Immediate(0), + std::move(element)); + } else { + value = Operation(OperationCode::UBitwiseOr, value, + Operation(OperationCode::Select, comp, + std::move(element_value), std::move(element))); + } + } + SetRegister(bb, instr.gpr0.Value(), std::move(value)); break; } default: -- cgit v1.2.3 From 1f3d142875b11c3728eb6b7cf172f9d4c1645274 Mon Sep 17 00:00:00 2001 From: Nguyen Dac Nam Date: Wed, 11 Mar 2020 19:19:56 +0700 Subject: shader: image - import PredCondition --- src/video_core/shader/decode/image.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/video_core/shader/decode') diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index 077bad037..7c48c2f97 100644 --- a/src/video_core/shader/decode/image.cpp +++ b/src/video_core/shader/decode/image.cpp @@ -19,6 +19,7 @@ namespace VideoCommon::Shader { using Tegra::Shader::Instruction; using Tegra::Shader::OpCode; using Tegra::Shader::StoreType; +using Tegra::Shader::PredCondition; namespace { std::size_t GetImageTypeNumCoordinates(Tegra::Shader::ImageType image_type) { -- cgit v1.2.3 From 2cefdd92bd569650c0b7459cb6a721d3aec43d1e Mon Sep 17 00:00:00 2001 From: Nguyen Dac Nam Date: Wed, 11 Mar 2020 21:11:11 +0700 Subject: clang-fix --- src/video_core/shader/decode/image.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/video_core/shader/decode') diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index 7c48c2f97..3eb657099 100644 --- a/src/video_core/shader/decode/image.cpp +++ b/src/video_core/shader/decode/image.cpp @@ -18,8 +18,8 @@ namespace VideoCommon::Shader { using Tegra::Shader::Instruction; using Tegra::Shader::OpCode; -using Tegra::Shader::StoreType; using Tegra::Shader::PredCondition; +using Tegra::Shader::StoreType; namespace { std::size_t GetImageTypeNumCoordinates(Tegra::Shader::ImageType image_type) { -- cgit v1.2.3 From f24c2e11035dd31deadebb14f9737cb31f73158e Mon Sep 17 00:00:00 2001 From: namkazy Date: Sun, 22 Mar 2020 20:14:12 +0700 Subject: [wip] reimplement SULD.D --- src/video_core/shader/decode/image.cpp | 251 ++++++++++++++++++++++++++++++--- 1 file changed, 229 insertions(+), 22 deletions(-) (limited to 'src/video_core/shader/decode') diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index 3eb657099..feb451452 100644 --- a/src/video_core/shader/decode/image.cpp +++ b/src/video_core/shader/decode/image.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#pragma optimize("", off) + #include #include #include @@ -10,9 +12,12 @@ #include "common/bit_field.h" #include "common/common_types.h" #include "common/logging/log.h" +#include "core/core.h" +#include "video_core/engines/maxwell_3d.h" #include "video_core/engines/shader_bytecode.h" #include "video_core/shader/node_helper.h" #include "video_core/shader/shader_ir.h" +#include "video_core/textures/texture.h" namespace VideoCommon::Shader { @@ -20,8 +25,162 @@ using Tegra::Shader::Instruction; using Tegra::Shader::OpCode; using Tegra::Shader::PredCondition; using Tegra::Shader::StoreType; +using Tegra::Texture::ComponentType; +using Tegra::Texture::TextureFormat; +using Tegra::Texture::TICEntry; namespace { +ComponentType GetComponentType(TICEntry tic, std::size_t component) { + constexpr u8 R = 0b0001; + constexpr u8 G = 0b0010; + constexpr u8 B = 0b0100; + constexpr u8 A = 0b1000; + if (R & component) { + return tic.r_type; + } + if (G & component) { + return tic.g_type; + } + if (B & component) { + return tic.b_type; + } + if (A & component) { + return tic.a_type; + } + return ComponentType::FLOAT; +} + +bool IsComponentEnabled(std::size_t component_mask, std::size_t component) { + constexpr u8 R = 0b0001; + constexpr u8 G = 0b0010; + constexpr u8 B = 0b0100; + constexpr u8 A = 0b1000; + constexpr std::array mask = { + 0, (R), (G), (R | G), (B), (R | B), (G | B), (R | G | B), + (A), (R | A), (G | A), (R | G | A), (B | A), (R | B | A), (G | B | A), (R | G | B | A)}; + return std::bitset<4>{mask.at(component_mask)}.test(component); +} + +u32 GetComponentSize(TextureFormat format, std::size_t component) { + switch (format) { + case TextureFormat::R32_G32_B32_A32: + return 32; + case TextureFormat::R16_G16_B16_A16: + return 16; + case TextureFormat::R32_G32_B32: + return (0 == component || 1 == component || 2 == component) ? 32 : 0; + case TextureFormat::R32_G32: + return (0 == component || 1 == component) ? 32 : 0; + case TextureFormat::R16_G16: + return (0 == component || 1 == component) ? 16 : 0; + case TextureFormat::R32: + return (0 == component) ? 32 : 0; + case TextureFormat::R16: + return (0 == component) ? 16 : 0; + case TextureFormat::R8: + return (0 == component) ? 8 : 0; + case TextureFormat::R1: + return (0 == component) ? 1 : 0; + case TextureFormat::A8R8G8B8: + return 8; + case TextureFormat::A2B10G10R10: + return (3 == component || 2 == component || 1 == component) ? 10 : 2; + case TextureFormat::A4B4G4R4: + return 4; + case TextureFormat::A5B5G5R1: + return (0 == component || 1 == component || 2 == component) ? 5 : 1; + case TextureFormat::A1B5G5R5: + return (1 == component || 2 == component || 3 == component) ? 5 : 1; + case TextureFormat::R32_B24G8: + if (0 == component) { + return 32; + } + if (1 == component) { + return 24; + } + if (2 == component) { + return 8; + } + return 0; + case TextureFormat::B5G6R5: + if (0 == component || 2 == component) { + return 5; + } + if (1 == component) { + return 6; + } + return 0; + case TextureFormat::B6G5R5: + if (1 == component || 2 == component) { + return 5; + } + if (0 == component) { + return 6; + } + return 0; + case TextureFormat::G8R24: + if (0 == component) { + return 8; + } + if (1 == component) { + return 24; + } + return 0; + case TextureFormat::G24R8: + if (0 == component) { + return 8; + } + if (1 == component) { + return 24; + } + return 0; + case TextureFormat::G8R8: + return (0 == component || 1 == component) ? 8 : 0; + case TextureFormat::G4R4: + return (0 == component || 1 == component) ? 4 : 0; + default: + UNIMPLEMENTED_MSG("texture format not implement={}", format); + return 0; + } +} + +std::size_t GetImageComponentMask(TextureFormat format) { + constexpr u8 R = 0b0001; + constexpr u8 G = 0b0010; + constexpr u8 B = 0b0100; + constexpr u8 A = 0b1000; + switch (format) { + case TextureFormat::R32_G32_B32_A32: + case TextureFormat::R16_G16_B16_A16: + case TextureFormat::A8R8G8B8: + case TextureFormat::A2B10G10R10: + case TextureFormat::A4B4G4R4: + case TextureFormat::A5B5G5R1: + case TextureFormat::A1B5G5R5: + return std::size_t{R | G | B | A}; + case TextureFormat::R32_G32_B32: + case TextureFormat::R32_B24G8: + case TextureFormat::B5G6R5: + case TextureFormat::B6G5R5: + return std::size_t{R | G | B}; + case TextureFormat::R32_G32: + case TextureFormat::R16_G16: + case TextureFormat::G8R24: + case TextureFormat::G24R8: + case TextureFormat::G8R8: + case TextureFormat::G4R4: + return std::size_t{R | G}; + case TextureFormat::R32: + case TextureFormat::R16: + case TextureFormat::R8: + case TextureFormat::R1: + return std::size_t{R}; + default: + UNIMPLEMENTED_MSG("texture format not implement={}", format); + return std::size_t{R | G | B | A}; + } +} + std::size_t GetImageTypeNumCoordinates(Tegra::Shader::ImageType image_type) { switch (image_type) { case Tegra::Shader::ImageType::Texture1D: @@ -79,36 +238,84 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { } else if (instr.suldst.mode == Tegra::Shader::SurfaceDataMode::D_BA) { UNIMPLEMENTED_IF(instr.suldst.GetStoreDataLayout() != StoreType::Bits32); + const auto maxwell3d = &Core::System::GetInstance().GPU().Maxwell3D(); + const auto tex_info = maxwell3d->GetStageTexture(shader_stage, image.GetOffset()); + + const auto comp_mask = GetImageComponentMask(tex_info.tic.format); + // TODO(namkazt): let's suppose image format is same as store type. we check on it + // later. + switch (instr.suldst.GetStoreDataLayout()) { case StoreType::Bits32: { - Node value{}; - for (s32 i = 3; i >= 0; i--) { - MetaImage meta{image, {}, i}; - Node element_value = + u32 shifted_counter = 0; + Node value = Immediate(0); + for (u32 element = 0; element < 4; ++element) { + if (!IsComponentEnabled(comp_mask, element)) { + continue; + } + const auto component_type = GetComponentType(tex_info.tic, element); + const auto component_size = GetComponentSize(tex_info.tic.format, element); + bool is_signed = true; + MetaImage meta{image, {}, element}; + const Node original_value = Operation(OperationCode::ImageLoad, meta, GetCoordinates(type)); + Node converted_value = [&] { + switch (component_type) { + case ComponentType::SNORM: { + // range [-1.0, 1.0] + auto cnv_value = Operation(OperationCode::FMul, NO_PRECISE, + original_value, Immediate(128.f)); + return SignedOperation(OperationCode::ICastFloat, is_signed, NO_PRECISE, + std::move(cnv_value)); + return cnv_value; + } + case ComponentType::UNORM: { + // range [0.0, 1.0] + auto cnv_value = Operation(OperationCode::FMul, NO_PRECISE, + original_value, Immediate(255.f)); + is_signed = false; + return SignedOperation(OperationCode::ICastFloat, is_signed, NO_PRECISE, + std::move(cnv_value)); + return cnv_value; + } + case ComponentType::SINT: // range [-128,128] + return original_value; + case ComponentType::UINT: // range [0, 255] + is_signed = false; + return original_value; + case ComponentType::FLOAT: + if (component_size == 8) { + auto cnv_value = Operation(OperationCode::FMul, NO_PRECISE, + original_value, Immediate(255.f)); + return SignedOperation(OperationCode::ICastFloat, is_signed, + NO_PRECISE, std::move(cnv_value)); + } + return original_value; + default: + UNIMPLEMENTED_MSG("Unimplement component type={}", component_type); + return original_value; + } + }(); + // shift element to correct position + shifted_counter += component_size; + const auto shifted = 32 - shifted_counter; + if (shifted > 0) { + /* converted_value = + SignedOperation(OperationCode::ILogicalShiftLeft, is_signed, + std::move(converted_value), Immediate(shifted));*/ + } - const Node comp = GetPredicateComparisonFloat(PredCondition::GreaterEqual, - element_value, Immediate(1.0f)); - const Node mul = - Operation(OperationCode::Select, comp, Immediate(1.f), Immediate(255.f)); - - Node element = Operation(OperationCode::FMul, NO_PRECISE, element_value, mul); - element = SignedOperation(OperationCode::ICastFloat, true, NO_PRECISE, - std::move(element)); - element = Operation(OperationCode::ULogicalShiftLeft, std::move(element), - Immediate(8 * i)); - if (i == 3) { - //(namkazt) for now i'm force it to 0 at alpha component if color is in - // range (0-255) - value = Operation(OperationCode::Select, comp, Immediate(0), - std::move(element)); + // add value into result + if (element == 0) { + value = original_value; } else { - value = Operation(OperationCode::UBitwiseOr, value, - Operation(OperationCode::Select, comp, - std::move(element_value), std::move(element))); + value = + Operation(OperationCode::UBitwiseOr, value, std::move(converted_value)); } + break; } SetRegister(bb, instr.gpr0.Value(), std::move(value)); + break; } default: -- cgit v1.2.3 From 3ad06e9b2b0d72b8d5ae3a055f98b9855609d60d Mon Sep 17 00:00:00 2001 From: namkazy Date: Sun, 22 Mar 2020 20:16:45 +0700 Subject: remove disable optimize --- src/video_core/shader/decode/image.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/video_core/shader/decode') diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index feb451452..6bfa71925 100644 --- a/src/video_core/shader/decode/image.cpp +++ b/src/video_core/shader/decode/image.cpp @@ -2,8 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#pragma optimize("", off) - #include #include #include -- cgit v1.2.3 From 658112783d5719b95435170d00e63afb2ce75f28 Mon Sep 17 00:00:00 2001 From: namkazy Date: Sun, 22 Mar 2020 20:29:46 +0700 Subject: reimplement get component type, uncomment mistaken code --- src/video_core/shader/decode/image.cpp | 111 +++++++++++++++++++++++++++------ 1 file changed, 93 insertions(+), 18 deletions(-) (limited to 'src/video_core/shader/decode') diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index 6bfa71925..34010a162 100644 --- a/src/video_core/shader/decode/image.cpp +++ b/src/video_core/shader/decode/image.cpp @@ -29,22 +29,97 @@ using Tegra::Texture::TICEntry; namespace { ComponentType GetComponentType(TICEntry tic, std::size_t component) { - constexpr u8 R = 0b0001; - constexpr u8 G = 0b0010; - constexpr u8 B = 0b0100; - constexpr u8 A = 0b1000; - if (R & component) { - return tic.r_type; - } - if (G & component) { - return tic.g_type; - } - if (B & component) { - return tic.b_type; - } - if (A & component) { - return tic.a_type; + const TextureFormat format{tic.format}; + switch (format) { + case TextureFormat::R16_G16_B16_A16: + case TextureFormat::R32_G32_B32_A32: + case TextureFormat::R32_G32_B32: + case TextureFormat::R32_G32: + case TextureFormat::R16_G16: + case TextureFormat::R32: + case TextureFormat::R16: + case TextureFormat::R8: + case TextureFormat::R1: + if (0 == component) { + return tic.r_type; + } + if (1 == component) { + return tic.g_type; + } + if (2 == component) { + return tic.b_type; + } + if (3 == component) { + return tic.a_type; + } + break; + case TextureFormat::A8R8G8B8: + if (0 == component) { + return tic.a_type; + } + if (1 == component) { + return tic.r_type; + } + if (2 == component) { + return tic.g_type; + } + if (3 == component) { + return tic.b_type; + } + break; + case TextureFormat::A2B10G10R10: + case TextureFormat::A4B4G4R4: + case TextureFormat::A5B5G5R1: + case TextureFormat::A1B5G5R5: + if (0 == component) { + return tic.a_type; + } + if (1 == component) { + return tic.b_type; + } + if (2 == component) { + return tic.g_type; + } + if (3 == component) { + return tic.r_type; + } + break; + case TextureFormat::R32_B24G8: + if (0 == component) { + return tic.r_type; + } + if (1 == component) { + return tic.b_type; + } + if (2 == component) { + return tic.g_type; + } + break; + case TextureFormat::B5G6R5: + case TextureFormat::B6G5R5: + if (0 == component) { + return tic.b_type; + } + if (1 == component) { + return tic.g_type; + } + if (2 == component) { + return tic.r_type; + } + break; + case TextureFormat::G8R24: + case TextureFormat::G24R8: + case TextureFormat::G8R8: + case TextureFormat::G4R4: + if (0 == component) { + return tic.g_type; + } + if (1 == component) { + return tic.r_type; + } + break; } + UNIMPLEMENTED_MSG("texture format not implement={}", format); return ComponentType::FLOAT; } @@ -298,9 +373,9 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { shifted_counter += component_size; const auto shifted = 32 - shifted_counter; if (shifted > 0) { - /* converted_value = - SignedOperation(OperationCode::ILogicalShiftLeft, is_signed, - std::move(converted_value), Immediate(shifted));*/ + converted_value = + SignedOperation(OperationCode::ILogicalShiftLeft, is_signed, + std::move(converted_value), Immediate(shifted)); } // add value into result -- cgit v1.2.3 From 5cd585700069b0b277b41a434b3880839cca27d3 Mon Sep 17 00:00:00 2001 From: namkazy Date: Sun, 22 Mar 2020 20:34:52 +0700 Subject: cleanup debug code. --- src/video_core/shader/decode/image.cpp | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) (limited to 'src/video_core/shader/decode') diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index 34010a162..e6cc831fc 100644 --- a/src/video_core/shader/decode/image.cpp +++ b/src/video_core/shader/decode/image.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#pragma optimize("", off) + #include #include #include @@ -340,7 +342,6 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { original_value, Immediate(128.f)); return SignedOperation(OperationCode::ICastFloat, is_signed, NO_PRECISE, std::move(cnv_value)); - return cnv_value; } case ComponentType::UNORM: { // range [0.0, 1.0] @@ -349,7 +350,6 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { is_signed = false; return SignedOperation(OperationCode::ICastFloat, is_signed, NO_PRECISE, std::move(cnv_value)); - return cnv_value; } case ComponentType::SINT: // range [-128,128] return original_value; @@ -357,12 +357,6 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { is_signed = false; return original_value; case ComponentType::FLOAT: - if (component_size == 8) { - auto cnv_value = Operation(OperationCode::FMul, NO_PRECISE, - original_value, Immediate(255.f)); - return SignedOperation(OperationCode::ICastFloat, is_signed, - NO_PRECISE, std::move(cnv_value)); - } return original_value; default: UNIMPLEMENTED_MSG("Unimplement component type={}", component_type); @@ -379,12 +373,7 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { } // add value into result - if (element == 0) { - value = original_value; - } else { - value = - Operation(OperationCode::UBitwiseOr, value, std::move(converted_value)); - } + value = Operation(OperationCode::UBitwiseOr, value, std::move(converted_value)); break; } SetRegister(bb, instr.gpr0.Value(), std::move(value)); -- cgit v1.2.3 From 3e3afa9be646f218a417097d1bd139f2008a90e7 Mon Sep 17 00:00:00 2001 From: namkazy Date: Sun, 22 Mar 2020 20:39:16 +0700 Subject: cleanup unuse params --- src/video_core/shader/decode/image.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'src/video_core/shader/decode') diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index e6cc831fc..cc5d2424c 100644 --- a/src/video_core/shader/decode/image.cpp +++ b/src/video_core/shader/decode/image.cpp @@ -338,17 +338,17 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { switch (component_type) { case ComponentType::SNORM: { // range [-1.0, 1.0] - auto cnv_value = Operation(OperationCode::FMul, NO_PRECISE, - original_value, Immediate(128.f)); - return SignedOperation(OperationCode::ICastFloat, is_signed, NO_PRECISE, + auto cnv_value = + Operation(OperationCode::FMul, original_value, Immediate(128.f)); + return SignedOperation(OperationCode::ICastFloat, is_signed, std::move(cnv_value)); } case ComponentType::UNORM: { // range [0.0, 1.0] - auto cnv_value = Operation(OperationCode::FMul, NO_PRECISE, - original_value, Immediate(255.f)); + auto cnv_value = + Operation(OperationCode::FMul, original_value, Immediate(255.f)); is_signed = false; - return SignedOperation(OperationCode::ICastFloat, is_signed, NO_PRECISE, + return SignedOperation(OperationCode::ICastFloat, is_signed, std::move(cnv_value)); } case ComponentType::SINT: // range [-128,128] @@ -374,10 +374,8 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { // add value into result value = Operation(OperationCode::UBitwiseOr, value, std::move(converted_value)); - break; } SetRegister(bb, instr.gpr0.Value(), std::move(value)); - break; } default: -- cgit v1.2.3 From acd3f0ab37520e449471040c1b7ccc6208f8e823 Mon Sep 17 00:00:00 2001 From: namkazy Date: Sun, 22 Mar 2020 21:13:07 +0700 Subject: tweaking. --- src/video_core/shader/decode/image.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/video_core/shader/decode') diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index cc5d2424c..07eb36153 100644 --- a/src/video_core/shader/decode/image.cpp +++ b/src/video_core/shader/decode/image.cpp @@ -2,8 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#pragma optimize("", off) - #include #include #include @@ -323,6 +321,7 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { switch (instr.suldst.GetStoreDataLayout()) { case StoreType::Bits32: { u32 shifted_counter = 0; + // value should be RGBA format Node value = Immediate(0); for (u32 element = 0; element < 4; ++element) { if (!IsComponentEnabled(comp_mask, element)) { @@ -334,6 +333,7 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { MetaImage meta{image, {}, element}; const Node original_value = Operation(OperationCode::ImageLoad, meta, GetCoordinates(type)); + Node converted_value = [&] { switch (component_type) { case ComponentType::SNORM: { @@ -346,7 +346,7 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { case ComponentType::UNORM: { // range [0.0, 1.0] auto cnv_value = - Operation(OperationCode::FMul, original_value, Immediate(255.f)); + Operation(OperationCode::FMul, original_value, Immediate(256.f)); is_signed = false; return SignedOperation(OperationCode::ICastFloat, is_signed, std::move(cnv_value)); -- cgit v1.2.3 From 24cc64c5b36e349f4b949193dd16dc053da964ce Mon Sep 17 00:00:00 2001 From: namkazy Date: Sun, 5 Apr 2020 12:54:48 +0700 Subject: shader_decode: get sampler descriptor from registry. --- src/video_core/shader/decode/image.cpp | 170 ++++++++++++++++++--------------- 1 file changed, 93 insertions(+), 77 deletions(-) (limited to 'src/video_core/shader/decode') diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index 07eb36153..731f61ee8 100644 --- a/src/video_core/shader/decode/image.cpp +++ b/src/video_core/shader/decode/image.cpp @@ -10,8 +10,6 @@ #include "common/bit_field.h" #include "common/common_types.h" #include "common/logging/log.h" -#include "core/core.h" -#include "video_core/engines/maxwell_3d.h" #include "video_core/engines/shader_bytecode.h" #include "video_core/shader/node_helper.h" #include "video_core/shader/shader_ir.h" @@ -28,8 +26,10 @@ using Tegra::Texture::TextureFormat; using Tegra::Texture::TICEntry; namespace { -ComponentType GetComponentType(TICEntry tic, std::size_t component) { - const TextureFormat format{tic.format}; + + +ComponentType GetComponentType(Tegra::Engines::SamplerDescriptor descriptor, std::size_t component) { + const TextureFormat format{descriptor.format}; switch (format) { case TextureFormat::R16_G16_B16_A16: case TextureFormat::R32_G32_B32_A32: @@ -40,82 +40,82 @@ ComponentType GetComponentType(TICEntry tic, std::size_t component) { case TextureFormat::R16: case TextureFormat::R8: case TextureFormat::R1: - if (0 == component) { - return tic.r_type; + if (component == 0) { + return descriptor.r_type; } - if (1 == component) { - return tic.g_type; + if (component == 1) { + return descriptor.g_type; } - if (2 == component) { - return tic.b_type; + if (component == 2) { + return descriptor.b_type; } - if (3 == component) { - return tic.a_type; + if (component == 3) { + return descriptor.a_type; } break; case TextureFormat::A8R8G8B8: - if (0 == component) { - return tic.a_type; + if (component == 0) { + return descriptor.a_type; } - if (1 == component) { - return tic.r_type; + if (component == 1) { + return descriptor.r_type; } - if (2 == component) { - return tic.g_type; + if (component == 2) { + return descriptor.g_type; } - if (3 == component) { - return tic.b_type; + if (component == 3) { + return descriptor.b_type; } break; case TextureFormat::A2B10G10R10: case TextureFormat::A4B4G4R4: case TextureFormat::A5B5G5R1: case TextureFormat::A1B5G5R5: - if (0 == component) { - return tic.a_type; + if (component == 0) { + return descriptor.a_type; } - if (1 == component) { - return tic.b_type; + if (component == 1) { + return descriptor.b_type; } - if (2 == component) { - return tic.g_type; + if (component == 2) { + return descriptor.g_type; } - if (3 == component) { - return tic.r_type; + if (component == 3) { + return descriptor.r_type; } break; case TextureFormat::R32_B24G8: - if (0 == component) { - return tic.r_type; + if (component == 0) { + return descriptor.r_type; } - if (1 == component) { - return tic.b_type; + if (component == 1) { + return descriptor.b_type; } - if (2 == component) { - return tic.g_type; + if (component == 2) { + return descriptor.g_type; } break; case TextureFormat::B5G6R5: case TextureFormat::B6G5R5: - if (0 == component) { - return tic.b_type; + if (component == 0) { + return descriptor.b_type; } - if (1 == component) { - return tic.g_type; + if (component == 1) { + return descriptor.g_type; } - if (2 == component) { - return tic.r_type; + if (component == 2) { + return descriptor.r_type; } break; case TextureFormat::G8R24: case TextureFormat::G24R8: case TextureFormat::G8R8: case TextureFormat::G4R4: - if (0 == component) { - return tic.g_type; + if (component == 0) { + return descriptor.g_type; } - if (1 == component) { - return tic.r_type; + if (component == 1) { + return descriptor.r_type; } break; } @@ -141,76 +141,76 @@ u32 GetComponentSize(TextureFormat format, std::size_t component) { case TextureFormat::R16_G16_B16_A16: return 16; case TextureFormat::R32_G32_B32: - return (0 == component || 1 == component || 2 == component) ? 32 : 0; + return (component == 0 || component == 1 || component == 2) ? 32 : 0; case TextureFormat::R32_G32: - return (0 == component || 1 == component) ? 32 : 0; + return (component == 0 || component == 1) ? 32 : 0; case TextureFormat::R16_G16: - return (0 == component || 1 == component) ? 16 : 0; + return (component == 0 || component == 1) ? 16 : 0; case TextureFormat::R32: - return (0 == component) ? 32 : 0; + return (component == 0) ? 32 : 0; case TextureFormat::R16: - return (0 == component) ? 16 : 0; + return (component == 0) ? 16 : 0; case TextureFormat::R8: - return (0 == component) ? 8 : 0; + return (component == 0) ? 8 : 0; case TextureFormat::R1: - return (0 == component) ? 1 : 0; + return (component == 0) ? 1 : 0; case TextureFormat::A8R8G8B8: return 8; case TextureFormat::A2B10G10R10: - return (3 == component || 2 == component || 1 == component) ? 10 : 2; + return (component == 3 || component == 2 || component == 1) ? 10 : 2; case TextureFormat::A4B4G4R4: return 4; case TextureFormat::A5B5G5R1: - return (0 == component || 1 == component || 2 == component) ? 5 : 1; + return (component == 0 || component == 1 || component == 2) ? 5 : 1; case TextureFormat::A1B5G5R5: - return (1 == component || 2 == component || 3 == component) ? 5 : 1; + return (component == 1 || component == 2 || component == 3) ? 5 : 1; case TextureFormat::R32_B24G8: - if (0 == component) { + if (component == 0) { return 32; } - if (1 == component) { + if (component == 1) { return 24; } - if (2 == component) { + if (component == 2) { return 8; } return 0; case TextureFormat::B5G6R5: - if (0 == component || 2 == component) { + if (component == 0 || component == 2) { return 5; } - if (1 == component) { + if (component == 1) { return 6; } return 0; case TextureFormat::B6G5R5: - if (1 == component || 2 == component) { + if (component == 1 || component == 2) { return 5; } - if (0 == component) { + if (component == 0) { return 6; } return 0; case TextureFormat::G8R24: - if (0 == component) { + if (component == 0) { return 8; } - if (1 == component) { + if (component == 1) { return 24; } return 0; case TextureFormat::G24R8: - if (0 == component) { + if (component == 0) { return 8; } - if (1 == component) { + if (component == 1) { return 24; } return 0; case TextureFormat::G8R8: - return (0 == component || 1 == component) ? 8 : 0; + return (component == 0 || component == 1) ? 8 : 0; case TextureFormat::G4R4: - return (0 == component || 1 == component) ? 4 : 0; + return (component == 0 || component == 1) ? 4 : 0; default: UNIMPLEMENTED_MSG("texture format not implement={}", format); return 0; @@ -311,10 +311,23 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { } else if (instr.suldst.mode == Tegra::Shader::SurfaceDataMode::D_BA) { UNIMPLEMENTED_IF(instr.suldst.GetStoreDataLayout() != StoreType::Bits32); - const auto maxwell3d = &Core::System::GetInstance().GPU().Maxwell3D(); - const auto tex_info = maxwell3d->GetStageTexture(shader_stage, image.GetOffset()); + auto descriptor = [this, instr] { + std::optional descriptor; + if (instr.suldst.is_immediate) { + descriptor = registry.ObtainBoundSampler(instr.image.index.Value()); + } else { + const Node image_register = GetRegister(instr.gpr39); + const auto [base_image, buffer, offset] = TrackCbuf( + image_register, global_code, static_cast(global_code.size())); + descriptor = registry.ObtainBindlessSampler(buffer, offset); + } + if (!descriptor) { + UNREACHABLE_MSG("Failed to obtain image descriptor"); + } + return *descriptor; + }(); - const auto comp_mask = GetImageComponentMask(tex_info.tic.format); + const auto comp_mask = GetImageComponentMask(descriptor.format); // TODO(namkazt): let's suppose image format is same as store type. we check on it // later. @@ -327,8 +340,8 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { if (!IsComponentEnabled(comp_mask, element)) { continue; } - const auto component_type = GetComponentType(tex_info.tic, element); - const auto component_size = GetComponentSize(tex_info.tic.format, element); + const auto component_type = GetComponentType(descriptor, element); + const auto component_size = GetComponentSize(descriptor.format, element); bool is_signed = true; MetaImage meta{image, {}, element}; const Node original_value = @@ -339,20 +352,23 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { case ComponentType::SNORM: { // range [-1.0, 1.0] auto cnv_value = - Operation(OperationCode::FMul, original_value, Immediate(128.f)); + Operation(OperationCode::FAdd, original_value, Immediate(1.f)); + cnv_value = Operation(OperationCode::FMul, std::move(cnv_value), + Immediate(127.f)); + is_signed = false; return SignedOperation(OperationCode::ICastFloat, is_signed, std::move(cnv_value)); } case ComponentType::UNORM: { // range [0.0, 1.0] auto cnv_value = - Operation(OperationCode::FMul, original_value, Immediate(256.f)); + Operation(OperationCode::FMul, original_value, Immediate(255.f)); is_signed = false; return SignedOperation(OperationCode::ICastFloat, is_signed, std::move(cnv_value)); } case ComponentType::SINT: // range [-128,128] - return original_value; + return Operation(OperationCode::IAdd, original_value, Immediate(128)); case ComponentType::UINT: // range [0, 255] is_signed = false; return original_value; @@ -364,13 +380,13 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { } }(); // shift element to correct position - shifted_counter += component_size; - const auto shifted = 32 - shifted_counter; + const auto shifted = shifted_counter; if (shifted > 0) { converted_value = SignedOperation(OperationCode::ILogicalShiftLeft, is_signed, std::move(converted_value), Immediate(shifted)); } + shifted_counter += component_size; // add value into result value = Operation(OperationCode::UBitwiseOr, value, std::move(converted_value)); -- cgit v1.2.3 From 69657ff19c5db03a009f85f8cc6779cefa0d4970 Mon Sep 17 00:00:00 2001 From: namkazy Date: Sun, 5 Apr 2020 12:57:50 +0700 Subject: clang-format --- src/video_core/shader/decode/image.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/video_core/shader/decode') diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index 731f61ee8..c125674b2 100644 --- a/src/video_core/shader/decode/image.cpp +++ b/src/video_core/shader/decode/image.cpp @@ -27,8 +27,8 @@ using Tegra::Texture::TICEntry; namespace { - -ComponentType GetComponentType(Tegra::Engines::SamplerDescriptor descriptor, std::size_t component) { +ComponentType GetComponentType(Tegra::Engines::SamplerDescriptor descriptor, + std::size_t component) { const TextureFormat format{descriptor.format}; switch (format) { case TextureFormat::R16_G16_B16_A16: -- cgit v1.2.3 From 6f2b7087c28cb4fea46485987540f2b9a7a6640d Mon Sep 17 00:00:00 2001 From: namkazy Date: Sun, 5 Apr 2020 14:46:43 +0700 Subject: shader_decode: SULD.D fix decode SNORM component --- src/video_core/shader/decode/image.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'src/video_core/shader/decode') diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index c125674b2..efcf271dc 100644 --- a/src/video_core/shader/decode/image.cpp +++ b/src/video_core/shader/decode/image.cpp @@ -350,25 +350,24 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { Node converted_value = [&] { switch (component_type) { case ComponentType::SNORM: { + is_signed = true; // range [-1.0, 1.0] - auto cnv_value = - Operation(OperationCode::FAdd, original_value, Immediate(1.f)); - cnv_value = Operation(OperationCode::FMul, std::move(cnv_value), - Immediate(127.f)); - is_signed = false; - return SignedOperation(OperationCode::ICastFloat, is_signed, - std::move(cnv_value)); + auto cnv_value = Operation(OperationCode::FMul, original_value, Immediate(127.f)); + cnv_value = SignedOperation(OperationCode::ICastFloat, is_signed, + std::move(cnv_value)); + return BitfieldExtract(std::move(cnv_value), 0, 8); } case ComponentType::UNORM: { + is_signed = false; // range [0.0, 1.0] auto cnv_value = Operation(OperationCode::FMul, original_value, Immediate(255.f)); - is_signed = false; return SignedOperation(OperationCode::ICastFloat, is_signed, std::move(cnv_value)); } - case ComponentType::SINT: // range [-128,128] - return Operation(OperationCode::IAdd, original_value, Immediate(128)); + case ComponentType::SINT: // range [-128,127] + is_signed = true; + return original_value; case ComponentType::UINT: // range [0, 255] is_signed = false; return original_value; -- cgit v1.2.3 From 9f6ebccf066eb5b7c6b922dee30cf2fe6ee9d516 Mon Sep 17 00:00:00 2001 From: namkazy Date: Sun, 5 Apr 2020 15:18:42 +0700 Subject: shader_decode: SULD.D -> SINT actually same as UNORM. --- src/video_core/shader/decode/image.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src/video_core/shader/decode') diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index efcf271dc..999cfda78 100644 --- a/src/video_core/shader/decode/image.cpp +++ b/src/video_core/shader/decode/image.cpp @@ -352,11 +352,13 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { case ComponentType::SNORM: { is_signed = true; // range [-1.0, 1.0] - auto cnv_value = Operation(OperationCode::FMul, original_value, Immediate(127.f)); + auto cnv_value = + Operation(OperationCode::FMul, original_value, Immediate(127.f)); cnv_value = SignedOperation(OperationCode::ICastFloat, is_signed, - std::move(cnv_value)); + std::move(cnv_value)); return BitfieldExtract(std::move(cnv_value), 0, 8); } + case ComponentType::SINT: case ComponentType::UNORM: { is_signed = false; // range [0.0, 1.0] @@ -365,9 +367,6 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { return SignedOperation(OperationCode::ICastFloat, is_signed, std::move(cnv_value)); } - case ComponentType::SINT: // range [-128,127] - is_signed = true; - return original_value; case ComponentType::UINT: // range [0, 255] is_signed = false; return original_value; -- cgit v1.2.3 From 730f9b55b35e3b1871285760cca35219ebb871d0 Mon Sep 17 00:00:00 2001 From: namkazy Date: Sun, 5 Apr 2020 16:02:07 +0700 Subject: silent warning (conversion error) --- src/video_core/shader/decode/image.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/video_core/shader/decode') diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index 999cfda78..8d4530386 100644 --- a/src/video_core/shader/decode/image.cpp +++ b/src/video_core/shader/decode/image.cpp @@ -314,7 +314,8 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { auto descriptor = [this, instr] { std::optional descriptor; if (instr.suldst.is_immediate) { - descriptor = registry.ObtainBoundSampler(instr.image.index.Value()); + descriptor = + registry.ObtainBoundSampler(static_cast(instr.image.index.Value())); } else { const Node image_register = GetRegister(instr.gpr39); const auto [base_image, buffer, offset] = TrackCbuf( @@ -328,8 +329,6 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { }(); const auto comp_mask = GetImageComponentMask(descriptor.format); - // TODO(namkazt): let's suppose image format is same as store type. we check on it - // later. switch (instr.suldst.GetStoreDataLayout()) { case StoreType::Bits32: { -- cgit v1.2.3 From 2906372ba18b1c6238062c7ac91ccf9536fc649b Mon Sep 17 00:00:00 2001 From: namkazy Date: Mon, 6 Apr 2020 13:09:19 +0700 Subject: shader_decode: SULD.D implement bits64 and reverse shader ir init method to removed shader stage. --- src/video_core/shader/decode/image.cpp | 127 ++++++++++++++++++++++++--------- 1 file changed, 92 insertions(+), 35 deletions(-) (limited to 'src/video_core/shader/decode') diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index 8d4530386..68913085f 100644 --- a/src/video_core/shader/decode/image.cpp +++ b/src/video_core/shader/decode/image.cpp @@ -271,6 +271,40 @@ std::size_t GetImageTypeNumCoordinates(Tegra::Shader::ImageType image_type) { } } // Anonymous namespace +Node ShaderIR::GetComponentValue(ComponentType component_type, u32 component_size, + const Node original_value, bool* is_signed) { + switch (component_type) { + case ComponentType::SNORM: { + *is_signed = true; + // range [-1.0, 1.0] + auto cnv_value = Operation(OperationCode::FMul, original_value, + Immediate((1 << component_size) / 2.f - 1.f)); + cnv_value = SignedOperation(OperationCode::ICastFloat, is_signed, std::move(cnv_value)); + return BitfieldExtract(std::move(cnv_value), 0, component_size); + } + case ComponentType::SINT: + case ComponentType::UNORM: { + *is_signed = component_type == ComponentType::SINT; + // range [0.0, 1.0] + auto cnv_value = + Operation(OperationCode::FMul, original_value, Immediate((1 << component_size) - 1.f)); + return SignedOperation(OperationCode::ICastFloat, is_signed, std::move(cnv_value)); + } + case ComponentType::UINT: // range [0, (1 << component_size) - 1] + *is_signed = false; + return original_value; + case ComponentType::FLOAT: + if (component_size == 16) { + return Operation(OperationCode::HCastFloat, original_value); + } else { + return original_value; + } + default: + UNIMPLEMENTED_MSG("Unimplement component type={}", component_type); + return original_value; + } +} + u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { const Instruction instr = {program_code[pc]}; const auto opcode = OpCode::Decode(instr); @@ -309,7 +343,8 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { SetRegister(bb, instr.gpr0.Value() + i, GetTemporary(i)); } } else if (instr.suldst.mode == Tegra::Shader::SurfaceDataMode::D_BA) { - UNIMPLEMENTED_IF(instr.suldst.GetStoreDataLayout() != StoreType::Bits32); + UNIMPLEMENTED_IF(instr.suldst.GetStoreDataLayout() != StoreType::Bits32 && + instr.suldst.GetStoreDataLayout() != StoreType::Bits64); auto descriptor = [this, instr] { std::optional descriptor; @@ -333,7 +368,6 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { switch (instr.suldst.GetStoreDataLayout()) { case StoreType::Bits32: { u32 shifted_counter = 0; - // value should be RGBA format Node value = Immediate(0); for (u32 element = 0; element < 4; ++element) { if (!IsComponentEnabled(comp_mask, element)) { @@ -343,39 +377,12 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { const auto component_size = GetComponentSize(descriptor.format, element); bool is_signed = true; MetaImage meta{image, {}, element}; - const Node original_value = - Operation(OperationCode::ImageLoad, meta, GetCoordinates(type)); - - Node converted_value = [&] { - switch (component_type) { - case ComponentType::SNORM: { - is_signed = true; - // range [-1.0, 1.0] - auto cnv_value = - Operation(OperationCode::FMul, original_value, Immediate(127.f)); - cnv_value = SignedOperation(OperationCode::ICastFloat, is_signed, - std::move(cnv_value)); - return BitfieldExtract(std::move(cnv_value), 0, 8); - } - case ComponentType::SINT: - case ComponentType::UNORM: { - is_signed = false; - // range [0.0, 1.0] - auto cnv_value = - Operation(OperationCode::FMul, original_value, Immediate(255.f)); - return SignedOperation(OperationCode::ICastFloat, is_signed, - std::move(cnv_value)); - } - case ComponentType::UINT: // range [0, 255] - is_signed = false; - return original_value; - case ComponentType::FLOAT: - return original_value; - default: - UNIMPLEMENTED_MSG("Unimplement component type={}", component_type); - return original_value; - } - }(); + + Node converted_value = GetComponentValue( + component_type, component_size, + Operation(OperationCode::ImageLoad, meta, GetCoordinates(type)), + &is_signed); + // shift element to correct position const auto shifted = shifted_counter; if (shifted > 0) { @@ -391,6 +398,56 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { SetRegister(bb, instr.gpr0.Value(), std::move(value)); break; } + case StoreType::Bits64: { + u32 indexer = 0; + u32 shifted_counter = 0; + Node value = Immediate(0); + for (u32 element = 0; element < 4; ++element) { + if (!IsComponentEnabled(comp_mask, element)) { + continue; + } + const auto component_type = GetComponentType(descriptor, element); + const auto component_size = GetComponentSize(descriptor.format, element); + + bool is_signed = true; + MetaImage meta{image, {}, element}; + + Node converted_value = GetComponentValue( + component_type, component_size, + Operation(OperationCode::ImageLoad, meta, GetCoordinates(type)), + &is_signed); + + // shift element to correct position + const auto shifted = shifted_counter; + if (shifted > 0) { + converted_value = + SignedOperation(OperationCode::ILogicalShiftLeft, is_signed, + std::move(converted_value), Immediate(shifted)); + } + shifted_counter += component_size; + + // add value into result + value = Operation(OperationCode::UBitwiseOr, value, std::move(converted_value)); + + // if we shifted enough for 1 byte -> we save it into temp + if (shifted_counter >= 32) { + SetTemporary(bb, indexer++, std::move(value)); + + // we only use 2 bytes for bits64 + if (indexer >= 2) { + break; + } + + // reset counter and value to prepare pack next byte + value = Immediate(0); + shifted_counter = 0; + } + } + for (u32 i = 0; i < indexer; ++i) { + SetRegister(bb, instr.gpr0.Value() + i, GetTemporary(i)); + } + break; + } default: UNREACHABLE(); break; -- cgit v1.2.3 From 7f5696513f2de891015cf852af34e2ddafb9f171 Mon Sep 17 00:00:00 2001 From: namkazy Date: Mon, 6 Apr 2020 13:26:58 +0700 Subject: shader_decode: SULD.D fix conversion error. --- src/video_core/shader/decode/image.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/video_core/shader/decode') diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index 68913085f..96e8db618 100644 --- a/src/video_core/shader/decode/image.cpp +++ b/src/video_core/shader/decode/image.cpp @@ -278,7 +278,7 @@ Node ShaderIR::GetComponentValue(ComponentType component_type, u32 component_siz *is_signed = true; // range [-1.0, 1.0] auto cnv_value = Operation(OperationCode::FMul, original_value, - Immediate((1 << component_size) / 2.f - 1.f)); + Immediate(static_cast(1 << component_size) / 2.f - 1.f)); cnv_value = SignedOperation(OperationCode::ICastFloat, is_signed, std::move(cnv_value)); return BitfieldExtract(std::move(cnv_value), 0, component_size); } @@ -286,8 +286,8 @@ Node ShaderIR::GetComponentValue(ComponentType component_type, u32 component_siz case ComponentType::UNORM: { *is_signed = component_type == ComponentType::SINT; // range [0.0, 1.0] - auto cnv_value = - Operation(OperationCode::FMul, original_value, Immediate((1 << component_size) - 1.f)); + auto cnv_value = Operation(OperationCode::FMul, original_value, + Immediate(static_cast(1 << component_size) - 1.f)); return SignedOperation(OperationCode::ICastFloat, is_signed, std::move(cnv_value)); } case ComponentType::UINT: // range [0, (1 << component_size) - 1] -- cgit v1.2.3 From 9efa51311f1d5cbd4300c23623f4bc8aed88f9a9 Mon Sep 17 00:00:00 2001 From: namkazy Date: Mon, 6 Apr 2020 13:34:06 +0700 Subject: shader_decode: SULD.D avoid duplicate code block. --- src/video_core/shader/decode/image.cpp | 41 ++-------------------------------- 1 file changed, 2 insertions(+), 39 deletions(-) (limited to 'src/video_core/shader/decode') diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index 96e8db618..242cd6cc1 100644 --- a/src/video_core/shader/decode/image.cpp +++ b/src/video_core/shader/decode/image.cpp @@ -272,7 +272,7 @@ std::size_t GetImageTypeNumCoordinates(Tegra::Shader::ImageType image_type) { } // Anonymous namespace Node ShaderIR::GetComponentValue(ComponentType component_type, u32 component_size, - const Node original_value, bool* is_signed) { + Node original_value, bool* is_signed) { switch (component_type) { case ComponentType::SNORM: { *is_signed = true; @@ -366,38 +366,7 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { const auto comp_mask = GetImageComponentMask(descriptor.format); switch (instr.suldst.GetStoreDataLayout()) { - case StoreType::Bits32: { - u32 shifted_counter = 0; - Node value = Immediate(0); - for (u32 element = 0; element < 4; ++element) { - if (!IsComponentEnabled(comp_mask, element)) { - continue; - } - const auto component_type = GetComponentType(descriptor, element); - const auto component_size = GetComponentSize(descriptor.format, element); - bool is_signed = true; - MetaImage meta{image, {}, element}; - - Node converted_value = GetComponentValue( - component_type, component_size, - Operation(OperationCode::ImageLoad, meta, GetCoordinates(type)), - &is_signed); - - // shift element to correct position - const auto shifted = shifted_counter; - if (shifted > 0) { - converted_value = - SignedOperation(OperationCode::ILogicalShiftLeft, is_signed, - std::move(converted_value), Immediate(shifted)); - } - shifted_counter += component_size; - - // add value into result - value = Operation(OperationCode::UBitwiseOr, value, std::move(converted_value)); - } - SetRegister(bb, instr.gpr0.Value(), std::move(value)); - break; - } + case StoreType::Bits32: case StoreType::Bits64: { u32 indexer = 0; u32 shifted_counter = 0; @@ -432,12 +401,6 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { // if we shifted enough for 1 byte -> we save it into temp if (shifted_counter >= 32) { SetTemporary(bb, indexer++, std::move(value)); - - // we only use 2 bytes for bits64 - if (indexer >= 2) { - break; - } - // reset counter and value to prepare pack next byte value = Immediate(0); shifted_counter = 0; -- cgit v1.2.3 From 2c98e14d13c7611f488c351c5b42b1c58d4b33ea Mon Sep 17 00:00:00 2001 From: namkazy Date: Mon, 6 Apr 2020 13:46:55 +0700 Subject: shader_decode: SULD.D using std::pair instead of out parameter --- src/video_core/shader/decode/image.cpp | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) (limited to 'src/video_core/shader/decode') diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index 242cd6cc1..7ad908a0e 100644 --- a/src/video_core/shader/decode/image.cpp +++ b/src/video_core/shader/decode/image.cpp @@ -271,37 +271,36 @@ std::size_t GetImageTypeNumCoordinates(Tegra::Shader::ImageType image_type) { } } // Anonymous namespace -Node ShaderIR::GetComponentValue(ComponentType component_type, u32 component_size, - Node original_value, bool* is_signed) { +std::pair ShaderIR::GetComponentValue(ComponentType component_type, u32 component_size, + Node original_value) { switch (component_type) { case ComponentType::SNORM: { - *is_signed = true; // range [-1.0, 1.0] auto cnv_value = Operation(OperationCode::FMul, original_value, Immediate(static_cast(1 << component_size) / 2.f - 1.f)); - cnv_value = SignedOperation(OperationCode::ICastFloat, is_signed, std::move(cnv_value)); - return BitfieldExtract(std::move(cnv_value), 0, component_size); + cnv_value = Operation(OperationCode::ICastFloat, std::move(cnv_value)); + return {BitfieldExtract(std::move(cnv_value), 0, component_size), true}; } case ComponentType::SINT: case ComponentType::UNORM: { - *is_signed = component_type == ComponentType::SINT; + bool is_signed = component_type == ComponentType::SINT; // range [0.0, 1.0] auto cnv_value = Operation(OperationCode::FMul, original_value, Immediate(static_cast(1 << component_size) - 1.f)); - return SignedOperation(OperationCode::ICastFloat, is_signed, std::move(cnv_value)); + return {SignedOperation(OperationCode::ICastFloat, is_signed, std::move(cnv_value)), + is_signed}; } case ComponentType::UINT: // range [0, (1 << component_size) - 1] - *is_signed = false; - return original_value; + return {original_value, false}; case ComponentType::FLOAT: if (component_size == 16) { - return Operation(OperationCode::HCastFloat, original_value); + return {Operation(OperationCode::HCastFloat, original_value), true}; } else { - return original_value; + return {original_value, true}; } default: UNIMPLEMENTED_MSG("Unimplement component type={}", component_type); - return original_value; + return {original_value, true}; } } @@ -377,14 +376,11 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { } const auto component_type = GetComponentType(descriptor, element); const auto component_size = GetComponentSize(descriptor.format, element); - - bool is_signed = true; MetaImage meta{image, {}, element}; - Node converted_value = GetComponentValue( + auto [converted_value, is_signed] = GetComponentValue( component_type, component_size, - Operation(OperationCode::ImageLoad, meta, GetCoordinates(type)), - &is_signed); + Operation(OperationCode::ImageLoad, meta, GetCoordinates(type))); // shift element to correct position const auto shifted = shifted_counter; -- cgit v1.2.3 From bf1174c114650110ac50175a804fcc3336b8fe33 Mon Sep 17 00:00:00 2001 From: Nguyen Dac Nam Date: Tue, 7 Apr 2020 07:55:49 +0700 Subject: Apply suggestions from code review Co-Authored-By: Rodrigo Locatti --- src/video_core/shader/decode/image.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src/video_core/shader/decode') diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index 7ad908a0e..4e796c79c 100644 --- a/src/video_core/shader/decode/image.cpp +++ b/src/video_core/shader/decode/image.cpp @@ -141,19 +141,19 @@ u32 GetComponentSize(TextureFormat format, std::size_t component) { case TextureFormat::R16_G16_B16_A16: return 16; case TextureFormat::R32_G32_B32: - return (component == 0 || component == 1 || component == 2) ? 32 : 0; + return component <= 2 ? 32 : 0; case TextureFormat::R32_G32: - return (component == 0 || component == 1) ? 32 : 0; + return component <= 1 ? 32 : 0; case TextureFormat::R16_G16: - return (component == 0 || component == 1) ? 16 : 0; + return component <= 1 ? 16 : 0; case TextureFormat::R32: - return (component == 0) ? 32 : 0; + return component == 0 ? 32 : 0; case TextureFormat::R16: - return (component == 0) ? 16 : 0; + return component == 0 ? 16 : 0; case TextureFormat::R8: - return (component == 0) ? 8 : 0; + return component == 0 ? 8 : 0; case TextureFormat::R1: - return (component == 0) ? 1 : 0; + return component == 0 ? 1 : 0; case TextureFormat::A8R8G8B8: return 8; case TextureFormat::A2B10G10R10: @@ -296,11 +296,11 @@ std::pair ShaderIR::GetComponentValue(ComponentType component_type, if (component_size == 16) { return {Operation(OperationCode::HCastFloat, original_value), true}; } else { - return {original_value, true}; + return {std::move(original_value), true}; } default: UNIMPLEMENTED_MSG("Unimplement component type={}", component_type); - return {original_value, true}; + return {std::move(original_value), true}; } } -- cgit v1.2.3 From 935648ffa9fbb1a6b439d1199a7742795f20dd40 Mon Sep 17 00:00:00 2001 From: Nguyen Dac Nam Date: Tue, 7 Apr 2020 18:29:30 +0700 Subject: address nit. --- src/video_core/shader/decode/image.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/video_core/shader/decode') diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index 4e796c79c..0dd7a1196 100644 --- a/src/video_core/shader/decode/image.cpp +++ b/src/video_core/shader/decode/image.cpp @@ -291,7 +291,7 @@ std::pair ShaderIR::GetComponentValue(ComponentType component_type, is_signed}; } case ComponentType::UINT: // range [0, (1 << component_size) - 1] - return {original_value, false}; + return {std::move(original_value), false}; case ComponentType::FLOAT: if (component_size == 16) { return {Operation(OperationCode::HCastFloat, original_value), true}; -- cgit v1.2.3