Shader Decompiler: Check for shift when deriving composite samplers.
This commit is contained in:
parent
a283eda320
commit
ba34cf0a69
6 changed files with 46 additions and 11 deletions
|
@ -19,8 +19,10 @@ namespace {
|
||||||
struct ConstBufferAddr {
|
struct ConstBufferAddr {
|
||||||
u32 index;
|
u32 index;
|
||||||
u32 offset;
|
u32 offset;
|
||||||
|
u32 shift_left;
|
||||||
u32 secondary_index;
|
u32 secondary_index;
|
||||||
u32 secondary_offset;
|
u32 secondary_offset;
|
||||||
|
u32 secondary_shift_left;
|
||||||
IR::U32 dynamic_offset;
|
IR::U32 dynamic_offset;
|
||||||
u32 count;
|
u32 count;
|
||||||
bool has_secondary;
|
bool has_secondary;
|
||||||
|
@ -182,6 +184,7 @@ std::optional<ConstBufferAddr> TryGetConstBuffer(const IR::Inst* inst) {
|
||||||
switch (inst->GetOpcode()) {
|
switch (inst->GetOpcode()) {
|
||||||
default:
|
default:
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
|
case IR::Opcode::BitwiseXor32:
|
||||||
case IR::Opcode::BitwiseOr32: {
|
case IR::Opcode::BitwiseOr32: {
|
||||||
std::optional lhs{Track(inst->Arg(0))};
|
std::optional lhs{Track(inst->Arg(0))};
|
||||||
std::optional rhs{Track(inst->Arg(1))};
|
std::optional rhs{Track(inst->Arg(1))};
|
||||||
|
@ -194,19 +197,33 @@ std::optional<ConstBufferAddr> TryGetConstBuffer(const IR::Inst* inst) {
|
||||||
if (lhs->count > 1 || rhs->count > 1) {
|
if (lhs->count > 1 || rhs->count > 1) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
if (lhs->index > rhs->index || lhs->offset > rhs->offset) {
|
if (lhs->shift_left > 0 || lhs->index > rhs->index || lhs->offset > rhs->offset) {
|
||||||
std::swap(lhs, rhs);
|
std::swap(lhs, rhs);
|
||||||
}
|
}
|
||||||
return ConstBufferAddr{
|
return ConstBufferAddr{
|
||||||
.index = lhs->index,
|
.index = lhs->index,
|
||||||
.offset = lhs->offset,
|
.offset = lhs->offset,
|
||||||
|
.shift_left = lhs->shift_left,
|
||||||
.secondary_index = rhs->index,
|
.secondary_index = rhs->index,
|
||||||
.secondary_offset = rhs->offset,
|
.secondary_offset = rhs->offset,
|
||||||
|
.secondary_shift_left = rhs->shift_left,
|
||||||
.dynamic_offset = {},
|
.dynamic_offset = {},
|
||||||
.count = 1,
|
.count = 1,
|
||||||
.has_secondary = true,
|
.has_secondary = true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
case IR::Opcode::ShiftLeftLogical32: {
|
||||||
|
const IR::Value shift{inst->Arg(1)};
|
||||||
|
if (!shift.IsImmediate()) {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
std::optional lhs{Track(inst->Arg(0))};
|
||||||
|
if (lhs) {
|
||||||
|
lhs->shift_left = shift.U32();
|
||||||
|
}
|
||||||
|
return lhs;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case IR::Opcode::GetCbufU32x2:
|
case IR::Opcode::GetCbufU32x2:
|
||||||
case IR::Opcode::GetCbufU32:
|
case IR::Opcode::GetCbufU32:
|
||||||
break;
|
break;
|
||||||
|
@ -222,8 +239,10 @@ std::optional<ConstBufferAddr> TryGetConstBuffer(const IR::Inst* inst) {
|
||||||
return ConstBufferAddr{
|
return ConstBufferAddr{
|
||||||
.index = index.U32(),
|
.index = index.U32(),
|
||||||
.offset = offset.U32(),
|
.offset = offset.U32(),
|
||||||
|
.shift_left = 0,
|
||||||
.secondary_index = 0,
|
.secondary_index = 0,
|
||||||
.secondary_offset = 0,
|
.secondary_offset = 0,
|
||||||
|
.secondary_shift_left = 0,
|
||||||
.dynamic_offset = {},
|
.dynamic_offset = {},
|
||||||
.count = 1,
|
.count = 1,
|
||||||
.has_secondary = false,
|
.has_secondary = false,
|
||||||
|
@ -247,8 +266,10 @@ std::optional<ConstBufferAddr> TryGetConstBuffer(const IR::Inst* inst) {
|
||||||
return ConstBufferAddr{
|
return ConstBufferAddr{
|
||||||
.index = index.U32(),
|
.index = index.U32(),
|
||||||
.offset = base_offset,
|
.offset = base_offset,
|
||||||
|
.shift_left = 0,
|
||||||
.secondary_index = 0,
|
.secondary_index = 0,
|
||||||
.secondary_offset = 0,
|
.secondary_offset = 0,
|
||||||
|
.secondary_shift_left = 0,
|
||||||
.dynamic_offset = dynamic_offset,
|
.dynamic_offset = dynamic_offset,
|
||||||
.count = 8,
|
.count = 8,
|
||||||
.has_secondary = false,
|
.has_secondary = false,
|
||||||
|
@ -267,8 +288,10 @@ TextureInst MakeInst(Environment& env, IR::Block* block, IR::Inst& inst) {
|
||||||
addr = ConstBufferAddr{
|
addr = ConstBufferAddr{
|
||||||
.index = env.TextureBoundBuffer(),
|
.index = env.TextureBoundBuffer(),
|
||||||
.offset = inst.Arg(0).U32(),
|
.offset = inst.Arg(0).U32(),
|
||||||
|
.shift_left = 0,
|
||||||
.secondary_index = 0,
|
.secondary_index = 0,
|
||||||
.secondary_offset = 0,
|
.secondary_offset = 0,
|
||||||
|
.secondary_shift_left = 0,
|
||||||
.dynamic_offset = {},
|
.dynamic_offset = {},
|
||||||
.count = 1,
|
.count = 1,
|
||||||
.has_secondary = false,
|
.has_secondary = false,
|
||||||
|
@ -284,8 +307,9 @@ TextureInst MakeInst(Environment& env, IR::Block* block, IR::Inst& inst) {
|
||||||
TextureType ReadTextureType(Environment& env, const ConstBufferAddr& cbuf) {
|
TextureType ReadTextureType(Environment& env, const ConstBufferAddr& cbuf) {
|
||||||
const u32 secondary_index{cbuf.has_secondary ? cbuf.secondary_index : cbuf.index};
|
const u32 secondary_index{cbuf.has_secondary ? cbuf.secondary_index : cbuf.index};
|
||||||
const u32 secondary_offset{cbuf.has_secondary ? cbuf.secondary_offset : cbuf.offset};
|
const u32 secondary_offset{cbuf.has_secondary ? cbuf.secondary_offset : cbuf.offset};
|
||||||
const u32 lhs_raw{env.ReadCbufValue(cbuf.index, cbuf.offset)};
|
const u32 lhs_raw{env.ReadCbufValue(cbuf.index, cbuf.offset) << cbuf.shift_left};
|
||||||
const u32 rhs_raw{env.ReadCbufValue(secondary_index, secondary_offset)};
|
const u32 rhs_raw{env.ReadCbufValue(secondary_index, secondary_offset)
|
||||||
|
<< cbuf.secondary_shift_left};
|
||||||
return env.ReadTextureType(lhs_raw | rhs_raw);
|
return env.ReadTextureType(lhs_raw | rhs_raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -487,8 +511,10 @@ void TexturePass(Environment& env, IR::Program& program) {
|
||||||
.has_secondary = cbuf.has_secondary,
|
.has_secondary = cbuf.has_secondary,
|
||||||
.cbuf_index = cbuf.index,
|
.cbuf_index = cbuf.index,
|
||||||
.cbuf_offset = cbuf.offset,
|
.cbuf_offset = cbuf.offset,
|
||||||
|
.shift_left = cbuf.shift_left,
|
||||||
.secondary_cbuf_index = cbuf.secondary_index,
|
.secondary_cbuf_index = cbuf.secondary_index,
|
||||||
.secondary_cbuf_offset = cbuf.secondary_offset,
|
.secondary_cbuf_offset = cbuf.secondary_offset,
|
||||||
|
.secondary_shift_left = cbuf.secondary_shift_left,
|
||||||
.count = cbuf.count,
|
.count = cbuf.count,
|
||||||
.size_shift = DESCRIPTOR_SIZE_SHIFT,
|
.size_shift = DESCRIPTOR_SIZE_SHIFT,
|
||||||
});
|
});
|
||||||
|
@ -499,8 +525,10 @@ void TexturePass(Environment& env, IR::Program& program) {
|
||||||
.has_secondary = cbuf.has_secondary,
|
.has_secondary = cbuf.has_secondary,
|
||||||
.cbuf_index = cbuf.index,
|
.cbuf_index = cbuf.index,
|
||||||
.cbuf_offset = cbuf.offset,
|
.cbuf_offset = cbuf.offset,
|
||||||
|
.shift_left = cbuf.shift_left,
|
||||||
.secondary_cbuf_index = cbuf.secondary_index,
|
.secondary_cbuf_index = cbuf.secondary_index,
|
||||||
.secondary_cbuf_offset = cbuf.secondary_offset,
|
.secondary_cbuf_offset = cbuf.secondary_offset,
|
||||||
|
.secondary_shift_left = cbuf.secondary_shift_left,
|
||||||
.count = cbuf.count,
|
.count = cbuf.count,
|
||||||
.size_shift = DESCRIPTOR_SIZE_SHIFT,
|
.size_shift = DESCRIPTOR_SIZE_SHIFT,
|
||||||
});
|
});
|
||||||
|
|
|
@ -61,8 +61,10 @@ struct TextureBufferDescriptor {
|
||||||
bool has_secondary;
|
bool has_secondary;
|
||||||
u32 cbuf_index;
|
u32 cbuf_index;
|
||||||
u32 cbuf_offset;
|
u32 cbuf_offset;
|
||||||
|
u32 shift_left;
|
||||||
u32 secondary_cbuf_index;
|
u32 secondary_cbuf_index;
|
||||||
u32 secondary_cbuf_offset;
|
u32 secondary_cbuf_offset;
|
||||||
|
u32 secondary_shift_left;
|
||||||
u32 count;
|
u32 count;
|
||||||
u32 size_shift;
|
u32 size_shift;
|
||||||
};
|
};
|
||||||
|
@ -85,8 +87,10 @@ struct TextureDescriptor {
|
||||||
bool has_secondary;
|
bool has_secondary;
|
||||||
u32 cbuf_index;
|
u32 cbuf_index;
|
||||||
u32 cbuf_offset;
|
u32 cbuf_offset;
|
||||||
|
u32 shift_left;
|
||||||
u32 secondary_cbuf_index;
|
u32 secondary_cbuf_index;
|
||||||
u32 secondary_cbuf_offset;
|
u32 secondary_cbuf_offset;
|
||||||
|
u32 secondary_shift_left;
|
||||||
u32 count;
|
u32 count;
|
||||||
u32 size_shift;
|
u32 size_shift;
|
||||||
};
|
};
|
||||||
|
|
|
@ -100,8 +100,9 @@ void ComputePipeline::Configure() {
|
||||||
const u32 secondary_offset{desc.secondary_cbuf_offset + index_offset};
|
const u32 secondary_offset{desc.secondary_cbuf_offset + index_offset};
|
||||||
const GPUVAddr separate_addr{cbufs[desc.secondary_cbuf_index].Address() +
|
const GPUVAddr separate_addr{cbufs[desc.secondary_cbuf_index].Address() +
|
||||||
secondary_offset};
|
secondary_offset};
|
||||||
const u32 lhs_raw{gpu_memory->Read<u32>(addr)};
|
const u32 lhs_raw{gpu_memory->Read<u32>(addr) << desc.shift_left};
|
||||||
const u32 rhs_raw{gpu_memory->Read<u32>(separate_addr)};
|
const u32 rhs_raw{gpu_memory->Read<u32>(separate_addr)
|
||||||
|
<< desc.secondary_shift_left};
|
||||||
return TexturePair(lhs_raw | rhs_raw, via_header_index);
|
return TexturePair(lhs_raw | rhs_raw, via_header_index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -312,8 +312,9 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
|
||||||
const u32 second_offset{desc.secondary_cbuf_offset + index_offset};
|
const u32 second_offset{desc.secondary_cbuf_offset + index_offset};
|
||||||
const GPUVAddr separate_addr{cbufs[desc.secondary_cbuf_index].address +
|
const GPUVAddr separate_addr{cbufs[desc.secondary_cbuf_index].address +
|
||||||
second_offset};
|
second_offset};
|
||||||
const u32 lhs_raw{gpu_memory->Read<u32>(addr)};
|
const u32 lhs_raw{gpu_memory->Read<u32>(addr) << desc.shift_left};
|
||||||
const u32 rhs_raw{gpu_memory->Read<u32>(separate_addr)};
|
const u32 rhs_raw{gpu_memory->Read<u32>(separate_addr)
|
||||||
|
<< desc.secondary_shift_left};
|
||||||
const u32 raw{lhs_raw | rhs_raw};
|
const u32 raw{lhs_raw | rhs_raw};
|
||||||
return TexturePair(raw, via_header_index);
|
return TexturePair(raw, via_header_index);
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,8 +126,8 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute,
|
||||||
const u32 secondary_offset{desc.secondary_cbuf_offset + index_offset};
|
const u32 secondary_offset{desc.secondary_cbuf_offset + index_offset};
|
||||||
const GPUVAddr separate_addr{cbufs[desc.secondary_cbuf_index].Address() +
|
const GPUVAddr separate_addr{cbufs[desc.secondary_cbuf_index].Address() +
|
||||||
secondary_offset};
|
secondary_offset};
|
||||||
const u32 lhs_raw{gpu_memory.Read<u32>(addr)};
|
const u32 lhs_raw{gpu_memory.Read<u32>(addr) << desc.shift_left};
|
||||||
const u32 rhs_raw{gpu_memory.Read<u32>(separate_addr)};
|
const u32 rhs_raw{gpu_memory.Read<u32>(separate_addr) << desc.secondary_shift_left};
|
||||||
return TexturePair(lhs_raw | rhs_raw, via_header_index);
|
return TexturePair(lhs_raw | rhs_raw, via_header_index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -314,8 +314,9 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
|
||||||
const u32 second_offset{desc.secondary_cbuf_offset + index_offset};
|
const u32 second_offset{desc.secondary_cbuf_offset + index_offset};
|
||||||
const GPUVAddr separate_addr{cbufs[desc.secondary_cbuf_index].address +
|
const GPUVAddr separate_addr{cbufs[desc.secondary_cbuf_index].address +
|
||||||
second_offset};
|
second_offset};
|
||||||
const u32 lhs_raw{gpu_memory->Read<u32>(addr)};
|
const u32 lhs_raw{gpu_memory->Read<u32>(addr) << desc.shift_left};
|
||||||
const u32 rhs_raw{gpu_memory->Read<u32>(separate_addr)};
|
const u32 rhs_raw{gpu_memory->Read<u32>(separate_addr)
|
||||||
|
<< desc.secondary_shift_left};
|
||||||
const u32 raw{lhs_raw | rhs_raw};
|
const u32 raw{lhs_raw | rhs_raw};
|
||||||
return TexturePair(raw, via_header_index);
|
return TexturePair(raw, via_header_index);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue