forked from suyu/suyu
shader/decode: Remove extras from MetaTexture
This commit is contained in:
parent
48e6f77c03
commit
5ca63d0675
4 changed files with 65 additions and 40 deletions
|
@ -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 {
|
||||||
|
|
|
@ -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 += ')';
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue