shader/texture: Implement CUBE texture type for TMML and fix arrays

TMML takes an array argument that has no known meaning, this one appears
as the first component in gpr8 followed by s, t and r. Skip this
component when arrays are being used. Also implement CUBE texture types.

- Used by Pikmin 3: Deluxe Demo.
This commit is contained in:
ReinUsesLisp 2020-10-07 23:17:46 -03:00
parent 3446eb79b5
commit dffaffaac1
1 changed files with 22 additions and 19 deletions

View File

@ -292,33 +292,36 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
break; break;
} }
std::vector<Node> coords; const u64 base_index = is_array ? 1 : 0;
const u64 num_components = [texture_type] {
// TODO: Add coordinates for different samplers once other texture types are implemented.
switch (texture_type) { switch (texture_type) {
case TextureType::Texture1D: case TextureType::Texture1D:
coords.push_back(GetRegister(instr.gpr8)); return 1;
break;
case TextureType::Texture2D: case TextureType::Texture2D:
coords.push_back(GetRegister(instr.gpr8.Value() + 0)); return 2;
coords.push_back(GetRegister(instr.gpr8.Value() + 1)); case TextureType::TextureCube:
break; return 3;
default: default:
UNIMPLEMENTED_MSG("Unhandled texture type {}", static_cast<int>(texture_type)); UNIMPLEMENTED_MSG("Unhandled texture type {}", static_cast<int>(texture_type));
return 2;
// Fallback to interpreting as a 2D texture for now
coords.push_back(GetRegister(instr.gpr8.Value() + 0));
coords.push_back(GetRegister(instr.gpr8.Value() + 1));
} }
}();
// TODO: What's the array component used for?
std::vector<Node> coords;
coords.reserve(num_components);
for (u64 component = 0; component < num_components; ++component) {
coords.push_back(GetRegister(instr.gpr8.Value() + base_index + component));
}
u32 indexer = 0; u32 indexer = 0;
for (u32 element = 0; element < 2; ++element) { for (u32 element = 0; element < 2; ++element) {
if (!instr.tmml.IsComponentEnabled(element)) { if (!instr.tmml.IsComponentEnabled(element)) {
continue; continue;
} }
auto params = coords;
MetaTexture meta{*sampler, {}, {}, {}, {}, {}, {}, {}, {}, element, index_var}; MetaTexture meta{*sampler, {}, {}, {}, {}, {}, {}, {}, {}, element, index_var};
const Node value = Operation(OperationCode::TextureQueryLod, meta, std::move(params)); Node value = Operation(OperationCode::TextureQueryLod, meta, coords);
SetTemporary(bb, indexer++, value); SetTemporary(bb, indexer++, std::move(value));
} }
for (u32 i = 0; i < indexer; ++i) { for (u32 i = 0; i < indexer; ++i) {
SetRegister(bb, instr.gpr0.Value() + i, GetTemporary(i)); SetRegister(bb, instr.gpr0.Value() + i, GetTemporary(i));