From d62b0a9e2941eb9d43e84ee40fe1531c2dc92eea Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Tue, 29 Jan 2019 04:31:40 -0300 Subject: shader_ir: Clean texture management code Previous code relied on GLSL parameter order (something that's always ill-formed on an IR design). This approach passes spatial coordiantes through operation nodes and array and depth compare values in the the texture metadata. It still contains an "extra" vector containing generic nodes for bias and component index (for example) which is still a bit ill-formed but it should be better than the previous approach. --- .../renderer_opengl/gl_shader_decompiler.cpp | 73 ++++++++++++---------- 1 file changed, 41 insertions(+), 32 deletions(-) (limited to 'src/video_core/renderer_opengl') diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 70e124dc4..aecd4758a 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -719,45 +719,51 @@ private: constexpr std::array coord_constructors = {"float", "vec2", "vec3", "vec4"}; const auto meta = std::get_if(&operation.GetMeta()); - const auto count = static_cast(operation.GetOperandsCount()); ASSERT(meta); + const auto count = static_cast(operation.GetOperandsCount()); + const bool has_array = meta->sampler.IsArray(); + const bool has_shadow = meta->sampler.IsShadow(); + std::string expr = func; expr += '('; expr += GetSampler(meta->sampler); expr += ", "; - expr += coord_constructors[meta->coords_count - 1]; + expr += coord_constructors.at(count + (has_array ? 1 : 0) + (has_shadow ? 1 : 0) - 1); expr += '('; for (u32 i = 0; i < count; ++i) { - const bool is_extra = i >= meta->coords_count; - const bool is_array = i == meta->array_index; - - std::string operand = [&]() { - if (is_extra && is_extra_int) { - if (const auto immediate = std::get_if(operation[i])) { - return std::to_string(static_cast(immediate->GetValue())); - } else { - return "ftoi(" + Visit(operation[i]) + ')'; - } - } else { - return Visit(operation[i]); - } - }(); - if (is_array) { - ASSERT(!is_extra); - operand = "float(ftoi(" + operand + "))"; - } - - expr += operand; + expr += Visit(operation[i]); - if (i + 1 == meta->coords_count) { - expr += ')'; - } - if (i + 1 < count) { + const u32 next = i + 1; + if (next < count || has_array || has_shadow) + expr += ", "; + } + if (has_array) { + expr += "float(ftoi(" + Visit(meta->array) + "))"; + } + if (has_shadow) { + if (has_array) expr += ", "; + expr += Visit(meta->depth_compare); + } + expr += ')'; + + for (const Node extra : meta->extras) { + expr += ", "; + if (is_extra_int) { + if (const auto immediate = std::get_if(extra)) { + // Inline the string as an immediate integer in GLSL (some extra arguments are + // required to be constant) + expr += std::to_string(static_cast(immediate->GetValue())); + } else { + expr += "ftoi(" + Visit(extra) + ')'; + } + } else { + expr += Visit(extra); } } + expr += ')'; return expr; } @@ -1198,26 +1204,29 @@ private: std::string F4TexelFetch(Operation operation) { constexpr std::array constructors = {"int", "ivec2", "ivec3", "ivec4"}; const auto meta = std::get_if(&operation.GetMeta()); - const auto count = static_cast(operation.GetOperandsCount()); ASSERT(meta); + UNIMPLEMENTED_IF(meta->sampler.IsArray()); + UNIMPLEMENTED_IF(!meta->extras.empty()); + + const auto count = static_cast(operation.GetOperandsCount()); std::string expr = "texelFetch("; expr += GetSampler(meta->sampler); expr += ", "; - expr += constructors[meta->coords_count - 1]; + expr += constructors.at(count - 1); expr += '('; for (u32 i = 0; i < count; ++i) { expr += VisitOperand(operation, i, Type::Int); - if (i + 1 == meta->coords_count) { + const u32 next = i + 1; + if (next == count) expr += ')'; - } - if (i + 1 < count) { + if (next < count) expr += ", "; - } } expr += ')'; + return expr + GetSwizzle(meta->element); } -- cgit v1.2.3 From 889c646ac0d769e6c950e8ee75eb92b019def8c5 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Tue, 29 Jan 2019 04:39:07 -0300 Subject: shader_ir: Remove F4 prefix to texture operations This was originally included because texture operations returned a vec4. These operations now return a single float and the F4 prefix doesn't mean anything. --- .../renderer_opengl/gl_shader_decompiler.cpp | 24 +++++++++++----------- src/video_core/shader/decode/memory.cpp | 15 +++++++------- src/video_core/shader/shader_ir.h | 12 +++++------ 3 files changed, 25 insertions(+), 26 deletions(-) (limited to 'src/video_core/renderer_opengl') diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index aecd4758a..b39bb4843 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -1140,7 +1140,7 @@ private: Type::HalfFloat); } - std::string F4Texture(Operation operation) { + std::string Texture(Operation operation) { const auto meta = std::get_if(&operation.GetMeta()); ASSERT(meta); @@ -1151,7 +1151,7 @@ private: return expr + GetSwizzle(meta->element); } - std::string F4TextureLod(Operation operation) { + std::string TextureLod(Operation operation) { const auto meta = std::get_if(&operation.GetMeta()); ASSERT(meta); @@ -1162,7 +1162,7 @@ private: return expr + GetSwizzle(meta->element); } - std::string F4TextureGather(Operation operation) { + std::string TextureGather(Operation operation) { const auto meta = std::get_if(&operation.GetMeta()); ASSERT(meta); @@ -1170,7 +1170,7 @@ private: GetSwizzle(meta->element); } - std::string F4TextureQueryDimensions(Operation operation) { + std::string TextureQueryDimensions(Operation operation) { const auto meta = std::get_if(&operation.GetMeta()); ASSERT(meta); @@ -1190,7 +1190,7 @@ private: return "0"; } - std::string F4TextureQueryLod(Operation operation) { + std::string TextureQueryLod(Operation operation) { const auto meta = std::get_if(&operation.GetMeta()); ASSERT(meta); @@ -1201,7 +1201,7 @@ private: return "0"; } - std::string F4TexelFetch(Operation operation) { + std::string TexelFetch(Operation operation) { constexpr std::array constructors = {"int", "ivec2", "ivec3", "ivec4"}; const auto meta = std::get_if(&operation.GetMeta()); ASSERT(meta); @@ -1463,12 +1463,12 @@ private: &GLSLDecompiler::Logical2HNotEqual, &GLSLDecompiler::Logical2HGreaterEqual, - &GLSLDecompiler::F4Texture, - &GLSLDecompiler::F4TextureLod, - &GLSLDecompiler::F4TextureGather, - &GLSLDecompiler::F4TextureQueryDimensions, - &GLSLDecompiler::F4TextureQueryLod, - &GLSLDecompiler::F4TexelFetch, + &GLSLDecompiler::Texture, + &GLSLDecompiler::TextureLod, + &GLSLDecompiler::TextureGather, + &GLSLDecompiler::TextureQueryDimensions, + &GLSLDecompiler::TextureQueryLod, + &GLSLDecompiler::TexelFetch, &GLSLDecompiler::Branch, &GLSLDecompiler::PushFlowStack, diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp index be6ca044b..523421794 100644 --- a/src/video_core/shader/decode/memory.cpp +++ b/src/video_core/shader/decode/memory.cpp @@ -336,8 +336,7 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { for (u32 element = 0; element < values.size(); ++element) { auto coords_copy = coords; MetaTexture meta{sampler, {}, {}, extras, element}; - values[element] = - Operation(OperationCode::F4TextureGather, meta, std::move(coords_copy)); + values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy)); } WriteTexsInstructionFloat(bb, instr, values); @@ -362,8 +361,8 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { continue; } MetaTexture meta{sampler, {}, {}, {}, element}; - const Node value = Operation(OperationCode::F4TextureQueryDimensions, meta, - GetRegister(instr.gpr8)); + const Node value = + Operation(OperationCode::TextureQueryDimensions, meta, GetRegister(instr.gpr8)); SetTemporal(bb, indexer++, value); } for (u32 i = 0; i < indexer; ++i) { @@ -412,7 +411,7 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { for (u32 element = 0; element < 2; ++element) { auto params = coords; MetaTexture meta{sampler, {}, {}, {}, element}; - const Node value = Operation(OperationCode::F4TextureQueryLod, meta, std::move(params)); + const Node value = Operation(OperationCode::TextureQueryLod, meta, std::move(params)); SetTemporal(bb, element, value); } for (u32 element = 0; element < 2; ++element) { @@ -555,7 +554,7 @@ Node4 ShaderIR::GetTextureCode(Instruction instr, TextureType texture_type, (texture_type == Tegra::Shader::TextureType::TextureCube && is_array && is_shadow)); const OperationCode read_method = - lod_needed && gl_lod_supported ? OperationCode::F4TextureLod : OperationCode::F4Texture; + lod_needed && gl_lod_supported ? OperationCode::TextureLod : OperationCode::Texture; UNIMPLEMENTED_IF(process_mode != TextureProcessMode::None && !gl_lod_supported); @@ -671,7 +670,7 @@ Node4 ShaderIR::GetTld4Code(Instruction instr, TextureType texture_type, bool de for (u32 element = 0; element < values.size(); ++element) { auto coords_copy = coords; MetaTexture meta{sampler, GetRegister(array_register), {}, {}, element}; - values[element] = Operation(OperationCode::F4TextureGather, meta, std::move(coords_copy)); + values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy)); } return values; @@ -707,7 +706,7 @@ Node4 ShaderIR::GetTldsCode(Instruction instr, TextureType texture_type, bool is for (u32 element = 0; element < values.size(); ++element) { auto coords_copy = coords; MetaTexture meta{sampler, array, {}, {lod}, element}; - values[element] = Operation(OperationCode::F4TexelFetch, meta, std::move(coords_copy)); + values[element] = Operation(OperationCode::TexelFetch, meta, std::move(coords_copy)); } return values; } diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h index 0c3d9c61e..52c7f2c4e 100644 --- a/src/video_core/shader/shader_ir.h +++ b/src/video_core/shader/shader_ir.h @@ -156,12 +156,12 @@ enum class OperationCode { Logical2HNotEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2 Logical2HGreaterEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2 - F4Texture, /// (MetaTexture, float[N] coords, float[M] params) -> float4 - F4TextureLod, /// (MetaTexture, float[N] coords, float[M] params) -> float4 - F4TextureGather, /// (MetaTexture, float[N] coords, float[M] params) -> float4 - F4TextureQueryDimensions, /// (MetaTexture, float a) -> float4 - F4TextureQueryLod, /// (MetaTexture, float[N] coords) -> float4 - F4TexelFetch, /// (MetaTexture, int[N], int) -> float4 + Texture, /// (MetaTexture, float[N] coords) -> float4 + TextureLod, /// (MetaTexture, float[N] coords) -> float4 + TextureGather, /// (MetaTexture, float[N] coords) -> float4 + TextureQueryDimensions, /// (MetaTexture, float a) -> float4 + TextureQueryLod, /// (MetaTexture, float[N] coords) -> float4 + TexelFetch, /// (MetaTexture, int[N], int) -> float4 Branch, /// (uint branch_target) -> void PushFlowStack, /// (uint branch_target) -> void -- cgit v1.2.3