From 6d235b8631697b81b08ee6f10f2fc79dc2956a50 Mon Sep 17 00:00:00 2001 From: Nguyen Dac Nam Date: Mon, 9 Mar 2020 19:33:26 +0700 Subject: [PATCH 01/24] shader: implement SULD.D bits32 --- src/video_core/shader/decode/image.cpp | 38 ++++++++++++++++++-------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index d2fe4ec5dd..02bfef5240 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; } From ed1d8beb1318391ca4d4a305fdd37d85c7ecd1b1 Mon Sep 17 00:00:00 2001 From: Nguyen Dac Nam Date: Mon, 9 Mar 2020 20:13:25 +0700 Subject: [PATCH 02/24] shader: SULD.D import StoreType --- src/video_core/shader/decode/image.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index 02bfef5240..ae41e1149c 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) { From 08db60392da9eb82fba39f99c1e650085a7d094b Mon Sep 17 00:00:00 2001 From: Nguyen Dac Nam Date: Wed, 11 Mar 2020 18:15:31 +0700 Subject: [PATCH 03/24] shader: SULD.D bits32 implement more complexer method. --- src/video_core/shader/decode/image.cpp | 32 ++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index ae41e1149c..077bad0375 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: From 1f3d142875b11c3728eb6b7cf172f9d4c1645274 Mon Sep 17 00:00:00 2001 From: Nguyen Dac Nam Date: Wed, 11 Mar 2020 19:19:56 +0700 Subject: [PATCH 04/24] shader: image - import PredCondition --- src/video_core/shader/decode/image.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index 077bad0375..7c48c2f978 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) { From 2cefdd92bd569650c0b7459cb6a721d3aec43d1e Mon Sep 17 00:00:00 2001 From: Nguyen Dac Nam Date: Wed, 11 Mar 2020 21:11:11 +0700 Subject: [PATCH 05/24] clang-fix --- src/video_core/shader/decode/image.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index 7c48c2f978..3eb6570999 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) { From 58bcb86af54bb00e3a01db02c7ed1945b68ea44c Mon Sep 17 00:00:00 2001 From: namkazy Date: Sun, 22 Mar 2020 20:13:05 +0700 Subject: [PATCH 06/24] add shader stage when init shader ir --- src/video_core/renderer_opengl/gl_shader_cache.cpp | 6 +++--- src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | 3 ++- src/video_core/shader/shader_ir.cpp | 7 ++++--- src/video_core/shader/shader_ir.h | 5 +++-- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index 046ee55a59..dc6825a007 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp @@ -234,7 +234,7 @@ Shader CachedShader::CreateStageFromMemory(const ShaderParameters& params, const std::size_t size_in_bytes = code.size() * sizeof(u64); auto registry = std::make_shared(shader_type, params.system.GPU().Maxwell3D()); - const ShaderIR ir(code, STAGE_MAIN_OFFSET, COMPILER_SETTINGS, *registry); + const ShaderIR ir(code, shader_type, STAGE_MAIN_OFFSET, COMPILER_SETTINGS, *registry); // TODO(Rodrigo): Handle VertexA shaders // std::optional ir_b; // if (!code_b.empty()) { @@ -264,7 +264,7 @@ Shader CachedShader::CreateKernelFromMemory(const ShaderParameters& params, Prog auto& engine = params.system.GPU().KeplerCompute(); auto registry = std::make_shared(ShaderType::Compute, engine); - const ShaderIR ir(code, KERNEL_MAIN_OFFSET, COMPILER_SETTINGS, *registry); + const ShaderIR ir(code, ShaderType::Compute, KERNEL_MAIN_OFFSET, COMPILER_SETTINGS, *registry); const u64 uid = params.unique_identifier; auto program = BuildShader(params.device, ShaderType::Compute, uid, ir, *registry); @@ -341,7 +341,7 @@ void ShaderCacheOpenGL::LoadDiskCache(const std::atomic_bool& stop_loading, const bool is_compute = entry.type == ShaderType::Compute; const u32 main_offset = is_compute ? KERNEL_MAIN_OFFSET : STAGE_MAIN_OFFSET; auto registry = MakeRegistry(entry); - const ShaderIR ir(entry.code, main_offset, COMPILER_SETTINGS, *registry); + const ShaderIR ir(entry.code, entry.type, main_offset, COMPILER_SETTINGS, *registry); std::shared_ptr program; if (precompiled_entry) { diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 557b9d6625..c3e3884bec 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -162,7 +162,8 @@ CachedShader::CachedShader(Core::System& system, Tegra::Engines::ShaderType stag ProgramCode program_code, u32 main_offset) : RasterizerCacheObject{host_ptr}, gpu_addr{gpu_addr}, cpu_addr{cpu_addr}, program_code{std::move(program_code)}, registry{stage, GetEngine(system, stage)}, - shader_ir{this->program_code, main_offset, compiler_settings, registry}, + shader_ir{this->program_code, stage, main_offset, compiler_settings, + registry}, entries{GenerateShaderEntries(shader_ir)} {} CachedShader::~CachedShader() = default; diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp index baf7188d28..bbd86a2c59 100644 --- a/src/video_core/shader/shader_ir.cpp +++ b/src/video_core/shader/shader_ir.cpp @@ -24,9 +24,10 @@ using Tegra::Shader::PredCondition; using Tegra::Shader::PredOperation; using Tegra::Shader::Register; -ShaderIR::ShaderIR(const ProgramCode& program_code, u32 main_offset, CompilerSettings settings, - Registry& registry) - : program_code{program_code}, main_offset{main_offset}, settings{settings}, registry{registry} { +ShaderIR::ShaderIR(const ProgramCode& program_code, Tegra::Engines::ShaderType shader_stage, + u32 main_offset, CompilerSettings settings, Registry& registry) + : program_code{program_code}, shader_stage{shader_stage}, + main_offset{main_offset}, settings{settings}, registry{registry} { Decode(); PostDecode(); } diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h index 80fc9b82cc..e531181cdd 100644 --- a/src/video_core/shader/shader_ir.h +++ b/src/video_core/shader/shader_ir.h @@ -68,8 +68,8 @@ struct GlobalMemoryUsage { class ShaderIR final { public: - explicit ShaderIR(const ProgramCode& program_code, u32 main_offset, CompilerSettings settings, - Registry& registry); + explicit ShaderIR(const ProgramCode& program_code, Tegra::Engines::ShaderType shader_stage, + u32 main_offset, CompilerSettings settings, Registry& registry); ~ShaderIR(); const std::map& GetBasicBlocks() const { @@ -419,6 +419,7 @@ private: u32 NewCustomVariable(); const ProgramCode& program_code; + const Tegra::Engines::ShaderType shader_stage; const u32 main_offset; const CompilerSettings settings; Registry& registry; From f24c2e11035dd31deadebb14f9737cb31f73158e Mon Sep 17 00:00:00 2001 From: namkazy Date: Sun, 22 Mar 2020 20:14:12 +0700 Subject: [PATCH 07/24] [wip] reimplement SULD.D --- src/video_core/shader/decode/image.cpp | 257 ++++++++++++++++++++++--- 1 file changed, 232 insertions(+), 25 deletions(-) diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index 3eb6570999..feb4514529 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 = - 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))); + 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));*/ + } + + // add value into result + if (element == 0) { + value = original_value; + } else { + value = + Operation(OperationCode::UBitwiseOr, value, std::move(converted_value)); + } + break; } SetRegister(bb, instr.gpr0.Value(), std::move(value)); + break; } default: From 3ad06e9b2b0d72b8d5ae3a055f98b9855609d60d Mon Sep 17 00:00:00 2001 From: namkazy Date: Sun, 22 Mar 2020 20:16:45 +0700 Subject: [PATCH 08/24] remove disable optimize --- src/video_core/shader/decode/image.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index feb4514529..6bfa719259 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 From 658112783d5719b95435170d00e63afb2ce75f28 Mon Sep 17 00:00:00 2001 From: namkazy Date: Sun, 22 Mar 2020 20:29:46 +0700 Subject: [PATCH 09/24] reimplement get component type, uncomment mistaken code --- src/video_core/shader/decode/image.cpp | 111 +++++++++++++++++++++---- 1 file changed, 93 insertions(+), 18 deletions(-) diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index 6bfa719259..34010a162c 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 From 5cd585700069b0b277b41a434b3880839cca27d3 Mon Sep 17 00:00:00 2001 From: namkazy Date: Sun, 22 Mar 2020 20:34:52 +0700 Subject: [PATCH 10/24] cleanup debug code. --- src/video_core/shader/decode/image.cpp | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index 34010a162c..e6cc831fc6 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)); From 3e3afa9be646f218a417097d1bd139f2008a90e7 Mon Sep 17 00:00:00 2001 From: namkazy Date: Sun, 22 Mar 2020 20:39:16 +0700 Subject: [PATCH 11/24] cleanup unuse params --- src/video_core/shader/decode/image.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index e6cc831fc6..cc5d2424c0 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: From 8370188b3c18d323529e371a6bb8bfb8a54ec0b7 Mon Sep 17 00:00:00 2001 From: Nguyen Dac Nam Date: Sun, 22 Mar 2020 21:06:05 +0700 Subject: [PATCH 12/24] clang-format --- src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index c3e3884bec..7a8824ebc2 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -162,8 +162,7 @@ CachedShader::CachedShader(Core::System& system, Tegra::Engines::ShaderType stag ProgramCode program_code, u32 main_offset) : RasterizerCacheObject{host_ptr}, gpu_addr{gpu_addr}, cpu_addr{cpu_addr}, program_code{std::move(program_code)}, registry{stage, GetEngine(system, stage)}, - shader_ir{this->program_code, stage, main_offset, compiler_settings, - registry}, + shader_ir{this->program_code, stage, main_offset, compiler_settings, registry}, entries{GenerateShaderEntries(shader_ir)} {} CachedShader::~CachedShader() = default; From acd3f0ab37520e449471040c1b7ccc6208f8e823 Mon Sep 17 00:00:00 2001 From: namkazy Date: Sun, 22 Mar 2020 21:13:07 +0700 Subject: [PATCH 13/24] tweaking. --- src/video_core/shader/decode/image.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index cc5d2424c0..07eb361539 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)); From 24cc64c5b36e349f4b949193dd16dc053da964ce Mon Sep 17 00:00:00 2001 From: namkazy Date: Sun, 5 Apr 2020 12:54:48 +0700 Subject: [PATCH 14/24] shader_decode: get sampler descriptor from registry. --- src/video_core/shader/decode/image.cpp | 170 ++++++++++++++----------- 1 file changed, 93 insertions(+), 77 deletions(-) diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index 07eb361539..731f61ee84 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)); From 69657ff19c5db03a009f85f8cc6779cefa0d4970 Mon Sep 17 00:00:00 2001 From: namkazy Date: Sun, 5 Apr 2020 12:57:50 +0700 Subject: [PATCH 15/24] clang-format --- src/video_core/shader/decode/image.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index 731f61ee84..c125674b28 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: From 6f2b7087c28cb4fea46485987540f2b9a7a6640d Mon Sep 17 00:00:00 2001 From: namkazy Date: Sun, 5 Apr 2020 14:46:43 +0700 Subject: [PATCH 16/24] shader_decode: SULD.D fix decode SNORM component --- src/video_core/shader/decode/image.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index c125674b28..efcf271dcf 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; From 9f6ebccf066eb5b7c6b922dee30cf2fe6ee9d516 Mon Sep 17 00:00:00 2001 From: namkazy Date: Sun, 5 Apr 2020 15:18:42 +0700 Subject: [PATCH 17/24] shader_decode: SULD.D -> SINT actually same as UNORM. --- src/video_core/shader/decode/image.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index efcf271dcf..999cfda780 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; From 730f9b55b35e3b1871285760cca35219ebb871d0 Mon Sep 17 00:00:00 2001 From: namkazy Date: Sun, 5 Apr 2020 16:02:07 +0700 Subject: [PATCH 18/24] silent warning (conversion error) --- src/video_core/shader/decode/image.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index 999cfda780..8d45303861 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: { From 2906372ba18b1c6238062c7ac91ccf9536fc649b Mon Sep 17 00:00:00 2001 From: namkazy Date: Mon, 6 Apr 2020 13:09:19 +0700 Subject: [PATCH 19/24] shader_decode: SULD.D implement bits64 and reverse shader ir init method to removed shader stage. --- .../renderer_opengl/gl_shader_cache.cpp | 6 +- .../renderer_vulkan/vk_pipeline_cache.cpp | 2 +- src/video_core/shader/decode/image.cpp | 125 +++++++++++++----- src/video_core/shader/shader_ir.cpp | 7 +- src/video_core/shader/shader_ir.h | 9 +- 5 files changed, 104 insertions(+), 45 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index dc6825a007..046ee55a59 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp @@ -234,7 +234,7 @@ Shader CachedShader::CreateStageFromMemory(const ShaderParameters& params, const std::size_t size_in_bytes = code.size() * sizeof(u64); auto registry = std::make_shared(shader_type, params.system.GPU().Maxwell3D()); - const ShaderIR ir(code, shader_type, STAGE_MAIN_OFFSET, COMPILER_SETTINGS, *registry); + const ShaderIR ir(code, STAGE_MAIN_OFFSET, COMPILER_SETTINGS, *registry); // TODO(Rodrigo): Handle VertexA shaders // std::optional ir_b; // if (!code_b.empty()) { @@ -264,7 +264,7 @@ Shader CachedShader::CreateKernelFromMemory(const ShaderParameters& params, Prog auto& engine = params.system.GPU().KeplerCompute(); auto registry = std::make_shared(ShaderType::Compute, engine); - const ShaderIR ir(code, ShaderType::Compute, KERNEL_MAIN_OFFSET, COMPILER_SETTINGS, *registry); + const ShaderIR ir(code, KERNEL_MAIN_OFFSET, COMPILER_SETTINGS, *registry); const u64 uid = params.unique_identifier; auto program = BuildShader(params.device, ShaderType::Compute, uid, ir, *registry); @@ -341,7 +341,7 @@ void ShaderCacheOpenGL::LoadDiskCache(const std::atomic_bool& stop_loading, const bool is_compute = entry.type == ShaderType::Compute; const u32 main_offset = is_compute ? KERNEL_MAIN_OFFSET : STAGE_MAIN_OFFSET; auto registry = MakeRegistry(entry); - const ShaderIR ir(entry.code, entry.type, main_offset, COMPILER_SETTINGS, *registry); + const ShaderIR ir(entry.code, main_offset, COMPILER_SETTINGS, *registry); std::shared_ptr program; if (precompiled_entry) { diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 7a8824ebc2..557b9d6625 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -162,7 +162,7 @@ CachedShader::CachedShader(Core::System& system, Tegra::Engines::ShaderType stag ProgramCode program_code, u32 main_offset) : RasterizerCacheObject{host_ptr}, gpu_addr{gpu_addr}, cpu_addr{cpu_addr}, program_code{std::move(program_code)}, registry{stage, GetEngine(system, stage)}, - shader_ir{this->program_code, stage, main_offset, compiler_settings, registry}, + shader_ir{this->program_code, main_offset, compiler_settings, registry}, entries{GenerateShaderEntries(shader_ir)} {} CachedShader::~CachedShader() = default; diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index 8d45303861..68913085fc 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; diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp index bbd86a2c59..baf7188d28 100644 --- a/src/video_core/shader/shader_ir.cpp +++ b/src/video_core/shader/shader_ir.cpp @@ -24,10 +24,9 @@ using Tegra::Shader::PredCondition; using Tegra::Shader::PredOperation; using Tegra::Shader::Register; -ShaderIR::ShaderIR(const ProgramCode& program_code, Tegra::Engines::ShaderType shader_stage, - u32 main_offset, CompilerSettings settings, Registry& registry) - : program_code{program_code}, shader_stage{shader_stage}, - main_offset{main_offset}, settings{settings}, registry{registry} { +ShaderIR::ShaderIR(const ProgramCode& program_code, u32 main_offset, CompilerSettings settings, + Registry& registry) + : program_code{program_code}, main_offset{main_offset}, settings{settings}, registry{registry} { Decode(); PostDecode(); } diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h index e531181cdd..408cce71e0 100644 --- a/src/video_core/shader/shader_ir.h +++ b/src/video_core/shader/shader_ir.h @@ -68,8 +68,8 @@ struct GlobalMemoryUsage { class ShaderIR final { public: - explicit ShaderIR(const ProgramCode& program_code, Tegra::Engines::ShaderType shader_stage, - u32 main_offset, CompilerSettings settings, Registry& registry); + explicit ShaderIR(const ProgramCode& program_code, u32 main_offset, CompilerSettings settings, + Registry& registry); ~ShaderIR(); const std::map& GetBasicBlocks() const { @@ -312,6 +312,10 @@ private: /// Conditionally saturates a half float pair Node GetSaturatedHalfFloat(Node value, bool saturate = true); + /// Get image component value by type and size + Node GetComponentValue(Tegra::Texture::ComponentType component_type, u32 component_size, + const Node original_value, bool* is_signed); + /// Returns a predicate comparing two floats Node GetPredicateComparisonFloat(Tegra::Shader::PredCondition condition, Node op_a, Node op_b); /// Returns a predicate comparing two integers @@ -419,7 +423,6 @@ private: u32 NewCustomVariable(); const ProgramCode& program_code; - const Tegra::Engines::ShaderType shader_stage; const u32 main_offset; const CompilerSettings settings; Registry& registry; From 7f5696513f2de891015cf852af34e2ddafb9f171 Mon Sep 17 00:00:00 2001 From: namkazy Date: Mon, 6 Apr 2020 13:26:58 +0700 Subject: [PATCH 20/24] shader_decode: SULD.D fix conversion error. --- src/video_core/shader/decode/image.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index 68913085fc..96e8db6189 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] From 9efa51311f1d5cbd4300c23623f4bc8aed88f9a9 Mon Sep 17 00:00:00 2001 From: namkazy Date: Mon, 6 Apr 2020 13:34:06 +0700 Subject: [PATCH 21/24] shader_decode: SULD.D avoid duplicate code block. --- src/video_core/shader/decode/image.cpp | 41 ++------------------------ 1 file changed, 2 insertions(+), 39 deletions(-) diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index 96e8db6189..242cd6cc18 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; From 2c98e14d13c7611f488c351c5b42b1c58d4b33ea Mon Sep 17 00:00:00 2001 From: namkazy Date: Mon, 6 Apr 2020 13:46:55 +0700 Subject: [PATCH 22/24] shader_decode: SULD.D using std::pair instead of out parameter --- src/video_core/shader/decode/image.cpp | 30 +++++++++++--------------- src/video_core/shader/shader_ir.h | 4 ++-- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index 242cd6cc18..7ad908a0e0 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; diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h index 408cce71e0..ca6c976c93 100644 --- a/src/video_core/shader/shader_ir.h +++ b/src/video_core/shader/shader_ir.h @@ -313,8 +313,8 @@ private: Node GetSaturatedHalfFloat(Node value, bool saturate = true); /// Get image component value by type and size - Node GetComponentValue(Tegra::Texture::ComponentType component_type, u32 component_size, - const Node original_value, bool* is_signed); + std::pair GetComponentValue(Tegra::Texture::ComponentType component_type, + u32 component_size, Node original_value); /// Returns a predicate comparing two floats Node GetPredicateComparisonFloat(Tegra::Shader::PredCondition condition, Node op_a, Node op_b); From bf1174c114650110ac50175a804fcc3336b8fe33 Mon Sep 17 00:00:00 2001 From: Nguyen Dac Nam Date: Tue, 7 Apr 2020 07:55:49 +0700 Subject: [PATCH 23/24] 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(-) diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index 7ad908a0e0..4e796c79c3 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}; } } From 935648ffa9fbb1a6b439d1199a7742795f20dd40 Mon Sep 17 00:00:00 2001 From: Nguyen Dac Nam Date: Tue, 7 Apr 2020 18:29:30 +0700 Subject: [PATCH 24/24] address nit. --- src/video_core/shader/decode/image.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index 4e796c79c3..0dd7a1196c 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};