1
1
Fork 0
forked from suyu/suyu

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 {
None = 0,
LZ = 1, // Unknown, appears to be the same as none.
LZ = 1, // Load LOD of zero.
LB = 2, // Load Bias.
LL = 3, // Load LOD (LevelOfDetail)
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
LL = 3, // Load LOD.
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.
};
enum class TextureMiscMode : u64 {

View file

@ -5,7 +5,9 @@
#include <array>
#include <string>
#include <string_view>
#include <utility>
#include <variant>
#include <vector>
#include <fmt/format.h>
@ -717,7 +719,7 @@ private:
}
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"};
const auto meta = std::get_if<MetaTexture>(&operation.GetMeta());
@ -738,36 +740,47 @@ private:
expr += Visit(operation[i]);
const std::size_t next = i + 1;
if (next < count || has_array || has_shadow)
if (next < count)
expr += ", ";
}
if (has_array) {
expr += "float(ftoi(" + Visit(meta->array) + "))";
expr += ", float(ftoi(" + Visit(meta->array) + "))";
}
if (has_shadow) {
if (has_array)
expr += ", ";
expr += Visit(meta->depth_compare);
expr += ", " + Visit(meta->depth_compare);
}
expr += ')';
for (const Node extra : meta->extras) {
for (const auto& extra_pair : extras) {
const auto [type, operand] = extra_pair;
if (operand == nullptr) {
continue;
}
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
// required to be constant)
expr += std::to_string(static_cast<s32>(immediate->GetValue()));
} else {
expr += "ftoi(" + Visit(extra) + ')';
expr += "ftoi(" + Visit(operand) + ')';
}
} else {
expr += Visit(extra);
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;
}
}
}
expr += ')';
return expr;
return expr + ')';
}
std::string Assign(Operation operation) {
@ -1146,7 +1159,7 @@ private:
const auto meta = std::get_if<MetaTexture>(&operation.GetMeta());
ASSERT(meta);
std::string expr = GenerateTexture(operation, "texture");
std::string expr = GenerateTexture(operation, "texture", {{Type::Float, meta->bias}});
if (meta->sampler.IsShadow()) {
expr = "vec4(" + expr + ')';
}
@ -1157,7 +1170,7 @@ private:
const auto meta = std::get_if<MetaTexture>(&operation.GetMeta());
ASSERT(meta);
std::string expr = GenerateTexture(operation, "textureLod");
std::string expr = GenerateTexture(operation, "textureLod", {{Type::Float, meta->lod}});
if (meta->sampler.IsShadow()) {
expr = "vec4(" + expr + ')';
}
@ -1168,7 +1181,8 @@ private:
const auto meta = std::get_if<MetaTexture>(&operation.GetMeta());
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);
}
@ -1197,8 +1211,8 @@ private:
ASSERT(meta);
if (meta->element < 2) {
return "itof(int((" + GenerateTexture(operation, "textureQueryLod") + " * vec2(256))" +
GetSwizzle(meta->element) + "))";
return "itof(int((" + GenerateTexture(operation, "textureQueryLod", {}) +
" * vec2(256))" + GetSwizzle(meta->element) + "))";
}
return "0";
}
@ -1224,9 +1238,9 @@ private:
else if (next < count)
expr += ", ";
}
for (std::size_t i = 0; i < meta->extras.size(); ++i) {
if (meta->lod) {
expr += ", ";
expr += CastOperand(Visit(meta->extras.at(i)), Type::Int);
expr += CastOperand(Visit(meta->lod), Type::Int);
}
expr += ')';

View file

@ -119,8 +119,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
coords.push_back(op_a);
coords.push_back(op_b);
}
std::vector<Node> extras;
extras.push_back(Immediate(static_cast<u32>(instr.tld4s.component)));
const Node component = Immediate(static_cast<u32>(instr.tld4s.component));
const auto& sampler =
GetSampler(instr.sampler, TextureType::Texture2D, false, depth_compare);
@ -128,7 +127,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
Node4 values;
for (u32 element = 0; element < values.size(); ++element) {
auto coords_copy = coords;
MetaTexture meta{sampler, {}, {}, extras, element};
MetaTexture meta{sampler, {}, {}, {}, {}, component, element};
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)) {
continue;
}
MetaTexture meta{sampler, {}, {}, {}, element};
MetaTexture meta{sampler, {}, {}, {}, {}, {}, element};
const Node value =
Operation(OperationCode::TextureQueryDimensions, meta, GetRegister(instr.gpr8));
SetTemporal(bb, indexer++, value);
@ -203,7 +202,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
for (u32 element = 0; element < 2; ++element) {
auto params = coords;
MetaTexture meta{sampler, {}, {}, {}, element};
MetaTexture meta{sampler, {}, {}, {}, {}, {}, element};
const Node value = Operation(OperationCode::TextureQueryLod, meta, std::move(params));
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));
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);
std::vector<Node> extras;
Node bias = {};
Node lod = {};
if (process_mode != TextureProcessMode::None && gl_lod_supported) {
if (process_mode == TextureProcessMode::LZ) {
extras.push_back(Immediate(0.0f));
} else {
switch (process_mode) {
case TextureProcessMode::LZ:
lod = Immediate(0.0f);
break;
case TextureProcessMode::LB:
// 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
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;
for (u32 element = 0; element < values.size(); ++element) {
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));
}
@ -462,7 +471,7 @@ Node4 ShaderIR::GetTld4Code(Instruction instr, TextureType texture_type, bool de
Node4 values;
for (u32 element = 0; element < values.size(); ++element) {
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));
}
@ -498,7 +507,7 @@ Node4 ShaderIR::GetTldsCode(Instruction instr, TextureType texture_type, bool is
Node4 values;
for (u32 element = 0; element < values.size(); ++element) {
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));
}
return values;

View file

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