mirror of
https://git.h3cjp.net/H3cJP/citra.git
synced 2024-12-26 21:26:59 +00:00
Implement texture offset support for TexelFetch and TextureGather and add offsets for Tlds
Formatting
This commit is contained in:
parent
b0a3915351
commit
fb54c38631
|
@ -1845,13 +1845,21 @@ private:
|
||||||
|
|
||||||
Expression TextureGather(Operation operation) {
|
Expression TextureGather(Operation operation) {
|
||||||
const auto& meta = std::get<MetaTexture>(operation.GetMeta());
|
const auto& meta = std::get<MetaTexture>(operation.GetMeta());
|
||||||
UNIMPLEMENTED_IF(!meta.aoffi.empty());
|
|
||||||
|
|
||||||
const Id coords = GetCoordinates(operation, Type::Float);
|
const Id coords = GetCoordinates(operation, Type::Float);
|
||||||
|
|
||||||
|
spv::ImageOperandsMask mask = spv::ImageOperandsMask::MaskNone;
|
||||||
|
std::vector<Id> operands{};
|
||||||
Id texture{};
|
Id texture{};
|
||||||
|
|
||||||
|
if (!meta.aoffi.empty()) {
|
||||||
|
mask = mask | spv::ImageOperandsMask::Offset;
|
||||||
|
operands.push_back(GetOffsetCoordinates(operation));
|
||||||
|
}
|
||||||
|
|
||||||
if (meta.sampler.is_shadow) {
|
if (meta.sampler.is_shadow) {
|
||||||
texture = OpImageDrefGather(t_float4, GetTextureSampler(operation), coords,
|
texture = OpImageDrefGather(t_float4, GetTextureSampler(operation), coords,
|
||||||
AsFloat(Visit(meta.depth_compare)));
|
AsFloat(Visit(meta.depth_compare)), mask, operands);
|
||||||
} else {
|
} else {
|
||||||
u32 component_value = 0;
|
u32 component_value = 0;
|
||||||
if (meta.component) {
|
if (meta.component) {
|
||||||
|
@ -1860,7 +1868,7 @@ private:
|
||||||
component_value = component->GetValue();
|
component_value = component->GetValue();
|
||||||
}
|
}
|
||||||
texture = OpImageGather(t_float4, GetTextureSampler(operation), coords,
|
texture = OpImageGather(t_float4, GetTextureSampler(operation), coords,
|
||||||
Constant(t_uint, component_value));
|
Constant(t_uint, component_value), mask, operands);
|
||||||
}
|
}
|
||||||
return GetTextureElement(operation, texture, Type::Float);
|
return GetTextureElement(operation, texture, Type::Float);
|
||||||
}
|
}
|
||||||
|
@ -1928,13 +1936,22 @@ private:
|
||||||
|
|
||||||
const Id image = GetTextureImage(operation);
|
const Id image = GetTextureImage(operation);
|
||||||
const Id coords = GetCoordinates(operation, Type::Int);
|
const Id coords = GetCoordinates(operation, Type::Int);
|
||||||
|
|
||||||
|
spv::ImageOperandsMask mask = spv::ImageOperandsMask::MaskNone;
|
||||||
|
std::vector<Id> operands{};
|
||||||
Id fetch;
|
Id fetch;
|
||||||
|
|
||||||
if (meta.lod && !meta.sampler.is_buffer) {
|
if (meta.lod && !meta.sampler.is_buffer) {
|
||||||
fetch = OpImageFetch(t_float4, image, coords, spv::ImageOperandsMask::Lod,
|
mask = mask | spv::ImageOperandsMask::Lod;
|
||||||
AsInt(Visit(meta.lod)));
|
operands.push_back(AsInt(Visit(meta.lod)));
|
||||||
} else {
|
|
||||||
fetch = OpImageFetch(t_float4, image, coords);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!meta.aoffi.empty()) {
|
||||||
|
mask = mask | spv::ImageOperandsMask::Offset;
|
||||||
|
operands.push_back(GetOffsetCoordinates(operation));
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch = OpImageFetch(t_float4, image, coords, mask, operands);
|
||||||
return GetTextureElement(operation, fetch, Type::Float);
|
return GetTextureElement(operation, fetch, Type::Float);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -330,6 +330,7 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
|
||||||
case StoreType::Bits32:
|
case StoreType::Bits32:
|
||||||
(this->*set_memory)(bb, GetAddress(0), GetRegister(instr.gpr0));
|
(this->*set_memory)(bb, GetAddress(0), GetRegister(instr.gpr0));
|
||||||
break;
|
break;
|
||||||
|
case StoreType::Unsigned16:
|
||||||
case StoreType::Signed16: {
|
case StoreType::Signed16: {
|
||||||
Node address = GetAddress(0);
|
Node address = GetAddress(0);
|
||||||
Node memory = (this->*get_memory)(address);
|
Node memory = (this->*get_memory)(address);
|
||||||
|
|
|
@ -806,6 +806,7 @@ Node4 ShaderIR::GetTldsCode(Instruction instr, TextureType texture_type, bool is
|
||||||
|
|
||||||
const std::size_t type_coord_count = GetCoordCount(texture_type);
|
const std::size_t type_coord_count = GetCoordCount(texture_type);
|
||||||
const bool lod_enabled = instr.tlds.GetTextureProcessMode() == TextureProcessMode::LL;
|
const bool lod_enabled = instr.tlds.GetTextureProcessMode() == TextureProcessMode::LL;
|
||||||
|
const bool aoffi_enabled = instr.tlds.UsesMiscMode(TextureMiscMode::AOFFI);
|
||||||
|
|
||||||
// If enabled arrays index is always stored in the gpr8 field
|
// If enabled arrays index is always stored in the gpr8 field
|
||||||
const u64 array_register = instr.gpr8.Value();
|
const u64 array_register = instr.gpr8.Value();
|
||||||
|
@ -820,17 +821,23 @@ Node4 ShaderIR::GetTldsCode(Instruction instr, TextureType texture_type, bool is
|
||||||
std::vector<Node> coords;
|
std::vector<Node> coords;
|
||||||
for (std::size_t i = 0; i < type_coord_count; ++i) {
|
for (std::size_t i = 0; i < type_coord_count; ++i) {
|
||||||
const bool last = (i == (type_coord_count - 1)) && (type_coord_count > 1);
|
const bool last = (i == (type_coord_count - 1)) && (type_coord_count > 1);
|
||||||
coords.push_back(GetRegister(last ? last_coord_register : coord_register + i));
|
coords.push_back(
|
||||||
|
GetRegister(last && !aoffi_enabled ? last_coord_register : coord_register + i));
|
||||||
}
|
}
|
||||||
|
|
||||||
const Node array = is_array ? GetRegister(array_register) : nullptr;
|
const Node array = is_array ? GetRegister(array_register) : nullptr;
|
||||||
// When lod is used always is in gpr20
|
// When lod is used always is in gpr20
|
||||||
const Node lod = lod_enabled ? GetRegister(instr.gpr20) : Immediate(0);
|
const Node lod = lod_enabled ? GetRegister(instr.gpr20) : Immediate(0);
|
||||||
|
|
||||||
|
std::vector<Node> aoffi{};
|
||||||
|
if (aoffi_enabled) {
|
||||||
|
aoffi = GetAoffiCoordinates(GetRegister(instr.gpr20), type_coord_count, false);
|
||||||
|
}
|
||||||
|
|
||||||
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, {}, aoffi, {}, {}, {}, 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;
|
||||||
|
|
Loading…
Reference in a new issue