mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-06-26 20:36:16 +00:00
shader_recompiler: Add buffer offset calculation when swizzle is enabled. (#834)
This commit is contained in:
parent
fc90f279e2
commit
a49c7e9dcb
6 changed files with 41 additions and 3 deletions
|
@ -378,24 +378,45 @@ void PatchBufferInstruction(IR::Block& block, IR::Inst& inst, Info& info,
|
|||
// Replace handle with binding index in buffer resource list.
|
||||
IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)};
|
||||
inst.SetArg(0, ir.Imm32(binding));
|
||||
ASSERT(!buffer.swizzle_enable && !buffer.add_tid_enable);
|
||||
ASSERT(!buffer.add_tid_enable);
|
||||
|
||||
// Address of constant buffer reads can be calculated at IR emittion time.
|
||||
if (inst.GetOpcode() == IR::Opcode::ReadConstBuffer) {
|
||||
return;
|
||||
}
|
||||
|
||||
const IR::U32 index_stride = ir.Imm32(buffer.index_stride);
|
||||
const IR::U32 element_size = ir.Imm32(buffer.element_size);
|
||||
|
||||
// Compute address of the buffer using the stride.
|
||||
IR::U32 address = ir.Imm32(inst_info.inst_offset.Value());
|
||||
if (inst_info.index_enable) {
|
||||
const IR::U32 index = inst_info.offset_enable ? IR::U32{ir.CompositeExtract(inst.Arg(1), 0)}
|
||||
: IR::U32{inst.Arg(1)};
|
||||
address = ir.IAdd(address, ir.IMul(index, ir.Imm32(buffer.GetStride())));
|
||||
if (buffer.swizzle_enable) {
|
||||
const IR::U32 stride_index_stride =
|
||||
ir.Imm32(static_cast<u32>(buffer.stride * buffer.index_stride));
|
||||
const IR::U32 index_msb = ir.IDiv(index, index_stride);
|
||||
const IR::U32 index_lsb = ir.IMod(index, index_stride);
|
||||
address = ir.IAdd(address, ir.IAdd(ir.IMul(index_msb, stride_index_stride),
|
||||
ir.IMul(index_lsb, element_size)));
|
||||
} else {
|
||||
address = ir.IAdd(address, ir.IMul(index, ir.Imm32(buffer.GetStride())));
|
||||
}
|
||||
}
|
||||
if (inst_info.offset_enable) {
|
||||
const IR::U32 offset = inst_info.index_enable ? IR::U32{ir.CompositeExtract(inst.Arg(1), 1)}
|
||||
: IR::U32{inst.Arg(1)};
|
||||
address = ir.IAdd(address, offset);
|
||||
if (buffer.swizzle_enable) {
|
||||
const IR::U32 element_size_index_stride =
|
||||
ir.Imm32(buffer.element_size * buffer.index_stride);
|
||||
const IR::U32 offset_msb = ir.IDiv(offset, element_size);
|
||||
const IR::U32 offset_lsb = ir.IMod(offset, element_size);
|
||||
address = ir.IAdd(address,
|
||||
ir.IAdd(ir.IMul(offset_msb, element_size_index_stride), offset_lsb));
|
||||
} else {
|
||||
address = ir.IAdd(address, offset);
|
||||
}
|
||||
}
|
||||
inst.SetArg(1, address);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue