shader/decode: Remove extras from MetaTexture

This commit is contained in:
ReinUsesLisp 2019-02-22 03:30:12 -03:00
parent 48e6f77c03
commit 5ca63d0675
4 changed files with 65 additions and 40 deletions

View file

@ -325,11 +325,11 @@ enum class TextureQueryType : u64 {
enum class TextureProcessMode : u64 { enum class TextureProcessMode : u64 {
None = 0, None = 0,
LZ = 1, // Unknown, appears to be the same as none. LZ = 1, // Load LOD of zero.
LB = 2, // Load Bias. LB = 2, // Load Bias.
LL = 3, // Load LOD (LevelOfDetail) LL = 3, // Load LOD.
LBA = 6, // Load Bias. The A is unknown, does not appear to differ with LB LBA = 6, // Load Bias. The A is unknown, does not appear to differ with LB.
LLA = 7 // Load LOD. The A is unknown, does not appear to differ with LL LLA = 7 // Load LOD. The A is unknown, does not appear to differ with LL.
}; };
enum class TextureMiscMode : u64 { enum class TextureMiscMode : u64 {

View file

@ -5,7 +5,9 @@
#include <array> #include <array>
#include <string> #include <string>
#include <string_view> #include <string_view>
#include <utility>
#include <variant> #include <variant>
#include <vector>
#include <fmt/format.h> #include <fmt/format.h>
@ -717,7 +719,7 @@ private:
} }
std::string GenerateTexture(Operation operation, const std::string& func, std::string GenerateTexture(Operation operation, const std::string& func,
bool is_extra_int = false) { const std::vector<std::pair<Type, Node>>& extras) {
constexpr std::array<const char*, 4> coord_constructors = {"float", "vec2", "vec3", "vec4"}; constexpr std::array<const char*, 4> coord_constructors = {"float", "vec2", "vec3", "vec4"};
const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); const auto meta = std::get_if<MetaTexture>(&operation.GetMeta());
@ -738,36 +740,47 @@ private:
expr += Visit(operation[i]); expr += Visit(operation[i]);
const std::size_t next = i + 1; const std::size_t next = i + 1;
if (next < count || has_array || has_shadow) if (next < count)
expr += ", "; expr += ", ";
} }
if (has_array) { if (has_array) {
expr += "float(ftoi(" + Visit(meta->array) + "))"; expr += ", float(ftoi(" + Visit(meta->array) + "))";
} }
if (has_shadow) { if (has_shadow) {
if (has_array) expr += ", " + Visit(meta->depth_compare);
expr += ", ";
expr += Visit(meta->depth_compare);
} }
expr += ')'; expr += ')';
for (const Node extra : meta->extras) { for (const auto& extra_pair : extras) {
const auto [type, operand] = extra_pair;
if (operand == nullptr) {
continue;
}
expr += ", "; expr += ", ";
if (is_extra_int) {
if (const auto immediate = std::get_if<ImmediateNode>(extra)) { switch (type) {
case Type::Int:
if (const auto immediate = std::get_if<ImmediateNode>(operand)) {
// Inline the string as an immediate integer in GLSL (some extra arguments are // Inline the string as an immediate integer in GLSL (some extra arguments are
// required to be constant) // required to be constant)
expr += std::to_string(static_cast<s32>(immediate->GetValue())); expr += std::to_string(static_cast<s32>(immediate->GetValue()));
} else { } else {
expr += "ftoi(" + Visit(extra) + ')'; expr += "ftoi(" + Visit(operand) + ')';
}
break;
case Type::Float:
expr += Visit(operand);
break;
default: {
const auto type_int = static_cast<u32>(type);
UNIMPLEMENTED_MSG("Unimplemented extra type={}", type_int);
expr += '0';
break;
} }
} else {
expr += Visit(extra);
} }
} }
expr += ')'; return expr + ')';
return expr;
} }
std::string Assign(Operation operation) { std::string Assign(Operation operation) {
@ -1146,7 +1159,7 @@ private:
const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); const auto meta = std::get_if<MetaTexture>(&operation.GetMeta());
ASSERT(meta); ASSERT(meta);
std::string expr = GenerateTexture(operation, "texture"); std::string expr = GenerateTexture(operation, "texture", {{Type::Float, meta->bias}});
if (meta->sampler.IsShadow()) { if (meta->sampler.IsShadow()) {
expr = "vec4(" + expr + ')'; expr = "vec4(" + expr + ')';
} }
@ -1157,7 +1170,7 @@ private:
const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); const auto meta = std::get_if<MetaTexture>(&operation.GetMeta());
ASSERT(meta); ASSERT(meta);
std::string expr = GenerateTexture(operation, "textureLod"); std::string expr = GenerateTexture(operation, "textureLod", {{Type::Float, meta->lod}});
if (meta->sampler.IsShadow()) { if (meta->sampler.IsShadow()) {
expr = "vec4(" + expr + ')'; expr = "vec4(" + expr + ')';
} }
@ -1168,7 +1181,8 @@ private:
const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); const auto meta = std::get_if<MetaTexture>(&operation.GetMeta());
ASSERT(meta); ASSERT(meta);
return GenerateTexture(operation, "textureGather", !meta->sampler.IsShadow()) + const auto type = meta->sampler.IsShadow() ? Type::Float : Type::Int;
return GenerateTexture(operation, "textureGather", {{type, meta->component}}) +
GetSwizzle(meta->element); GetSwizzle(meta->element);
} }
@ -1197,8 +1211,8 @@ private:
ASSERT(meta); ASSERT(meta);
if (meta->element < 2) { if (meta->element < 2) {
return "itof(int((" + GenerateTexture(operation, "textureQueryLod") + " * vec2(256))" + return "itof(int((" + GenerateTexture(operation, "textureQueryLod", {}) +
GetSwizzle(meta->element) + "))"; " * vec2(256))" + GetSwizzle(meta->element) + "))";
} }
return "0"; return "0";
} }
@ -1224,9 +1238,9 @@ private:
else if (next < count) else if (next < count)
expr += ", "; expr += ", ";
} }
for (std::size_t i = 0; i < meta->extras.size(); ++i) { if (meta->lod) {
expr += ", "; expr += ", ";
expr += CastOperand(Visit(meta->extras.at(i)), Type::Int); expr += CastOperand(Visit(meta->lod), Type::Int);
} }
expr += ')'; expr += ')';

View file

@ -119,8 +119,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
coords.push_back(op_a); coords.push_back(op_a);
coords.push_back(op_b); coords.push_back(op_b);
} }
std::vector<Node> extras; const Node component = Immediate(static_cast<u32>(instr.tld4s.component));
extras.push_back(Immediate(static_cast<u32>(instr.tld4s.component)));
const auto& sampler = const auto& sampler =
GetSampler(instr.sampler, TextureType::Texture2D, false, depth_compare); GetSampler(instr.sampler, TextureType::Texture2D, false, depth_compare);
@ -128,7 +127,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
Node4 values; Node4 values;
for (u32 element = 0; element < values.size(); ++element) { for (u32 element = 0; element < values.size(); ++element) {
auto coords_copy = coords; auto coords_copy = coords;
MetaTexture meta{sampler, {}, {}, extras, element}; MetaTexture meta{sampler, {}, {}, {}, {}, component, element};
values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy)); values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy));
} }
@ -153,7 +152,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
if (!instr.txq.IsComponentEnabled(element)) { if (!instr.txq.IsComponentEnabled(element)) {
continue; continue;
} }
MetaTexture meta{sampler, {}, {}, {}, element}; MetaTexture meta{sampler, {}, {}, {}, {}, {}, element};
const Node value = const Node value =
Operation(OperationCode::TextureQueryDimensions, meta, GetRegister(instr.gpr8)); Operation(OperationCode::TextureQueryDimensions, meta, GetRegister(instr.gpr8));
SetTemporal(bb, indexer++, value); SetTemporal(bb, indexer++, value);
@ -203,7 +202,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
for (u32 element = 0; element < 2; ++element) { for (u32 element = 0; element < 2; ++element) {
auto params = coords; auto params = coords;
MetaTexture meta{sampler, {}, {}, {}, element}; MetaTexture meta{sampler, {}, {}, {}, {}, {}, element};
const Node value = Operation(OperationCode::TextureQueryLod, meta, std::move(params)); const Node value = Operation(OperationCode::TextureQueryLod, meta, std::move(params));
SetTemporal(bb, element, value); SetTemporal(bb, element, value);
} }
@ -347,25 +346,35 @@ Node4 ShaderIR::GetTextureCode(Instruction instr, TextureType texture_type,
(texture_type == Tegra::Shader::TextureType::TextureCube && is_array && is_shadow)); (texture_type == Tegra::Shader::TextureType::TextureCube && is_array && is_shadow));
const OperationCode read_method = const OperationCode read_method =
lod_needed && gl_lod_supported ? OperationCode::TextureLod : OperationCode::Texture; (lod_needed && gl_lod_supported) ? OperationCode::TextureLod : OperationCode::Texture;
UNIMPLEMENTED_IF(process_mode != TextureProcessMode::None && !gl_lod_supported); UNIMPLEMENTED_IF(process_mode != TextureProcessMode::None && !gl_lod_supported);
std::vector<Node> extras; Node bias = {};
Node lod = {};
if (process_mode != TextureProcessMode::None && gl_lod_supported) { if (process_mode != TextureProcessMode::None && gl_lod_supported) {
if (process_mode == TextureProcessMode::LZ) { switch (process_mode) {
extras.push_back(Immediate(0.0f)); case TextureProcessMode::LZ:
} else { lod = Immediate(0.0f);
break;
case TextureProcessMode::LB:
// If present, lod or bias are always stored in the register indexed by the gpr20 // If present, lod or bias are always stored in the register indexed by the gpr20
// field with an offset depending on the usage of the other registers // field with an offset depending on the usage of the other registers
extras.push_back(GetRegister(instr.gpr20.Value() + bias_offset)); bias = GetRegister(instr.gpr20.Value() + bias_offset);
break;
case TextureProcessMode::LL:
lod = GetRegister(instr.gpr20.Value() + bias_offset);
break;
default:
UNIMPLEMENTED_MSG("Unimplemented process mode={}", static_cast<u32>(process_mode));
break;
} }
} }
Node4 values; Node4 values;
for (u32 element = 0; element < values.size(); ++element) { for (u32 element = 0; element < values.size(); ++element) {
auto copy_coords = coords; auto copy_coords = coords;
MetaTexture meta{sampler, array, depth_compare, extras, element}; MetaTexture meta{sampler, array, depth_compare, bias, lod, {}, element};
values[element] = Operation(read_method, meta, std::move(copy_coords)); values[element] = Operation(read_method, meta, std::move(copy_coords));
} }
@ -462,7 +471,7 @@ Node4 ShaderIR::GetTld4Code(Instruction instr, TextureType texture_type, bool de
Node4 values; Node4 values;
for (u32 element = 0; element < values.size(); ++element) { for (u32 element = 0; element < values.size(); ++element) {
auto coords_copy = coords; auto coords_copy = coords;
MetaTexture meta{sampler, GetRegister(array_register), {}, {}, element}; MetaTexture meta{sampler, GetRegister(array_register), {}, {}, {}, {}, element};
values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy)); values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy));
} }
@ -498,7 +507,7 @@ Node4 ShaderIR::GetTldsCode(Instruction instr, TextureType texture_type, bool is
Node4 values; Node4 values;
for (u32 element = 0; element < values.size(); ++element) { for (u32 element = 0; element < values.size(); ++element) {
auto coords_copy = coords; auto coords_copy = coords;
MetaTexture meta{sampler, array, {}, {lod}, element}; MetaTexture meta{sampler, array, {}, {}, lod, {}, element};
values[element] = Operation(OperationCode::TexelFetch, meta, std::move(coords_copy)); values[element] = Operation(OperationCode::TexelFetch, meta, std::move(coords_copy));
} }
return values; return values;

View file

@ -290,7 +290,9 @@ struct MetaTexture {
const Sampler& sampler; const Sampler& sampler;
Node array{}; Node array{};
Node depth_compare{}; Node depth_compare{};
std::vector<Node> extras; Node bias{};
Node lod{};
Node component{};
u32 element{}; u32 element{};
}; };