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