mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 22:06:59 +01:00
Fold buffer address identities and remove empty predicates
This commit is contained in:
@@ -494,22 +494,18 @@ template <typename Fn>
|
|||||||
uint32_t EmitValueOrDefaultIfCondition(EmitterState& state, uint32_t condition, uint32_t type,
|
uint32_t EmitValueOrDefaultIfCondition(EmitterState& state, uint32_t condition, uint32_t type,
|
||||||
uint32_t default_value, Fn&& fn) {
|
uint32_t default_value, Fn&& fn) {
|
||||||
const auto then_label = state.builder.AllocateId();
|
const auto then_label = state.builder.AllocateId();
|
||||||
const auto then_exit = state.builder.AllocateId();
|
const auto header = state.current_label;
|
||||||
const auto else_label = state.builder.AllocateId();
|
|
||||||
const auto merge_label = state.builder.AllocateId();
|
const auto merge_label = state.builder.AllocateId();
|
||||||
state.builder.AddFunction(spv::OpSelectionMerge, merge_label, spv::SelectionControlMaskNone);
|
state.builder.AddFunction(spv::OpSelectionMerge, merge_label, spv::SelectionControlMaskNone);
|
||||||
state.builder.AddFunction(spv::OpBranchConditional, condition, then_label, else_label);
|
state.builder.AddFunction(spv::OpBranchConditional, condition, then_label, merge_label);
|
||||||
EmitLabel(state, then_label);
|
EmitLabel(state, then_label);
|
||||||
const auto then_value = fn();
|
const auto then_value = fn();
|
||||||
state.builder.AddFunction(spv::OpBranch, then_exit);
|
const auto then_exit = state.current_label;
|
||||||
EmitLabel(state, then_exit);
|
|
||||||
state.builder.AddFunction(spv::OpBranch, merge_label);
|
|
||||||
EmitLabel(state, else_label);
|
|
||||||
state.builder.AddFunction(spv::OpBranch, merge_label);
|
state.builder.AddFunction(spv::OpBranch, merge_label);
|
||||||
EmitLabel(state, merge_label);
|
EmitLabel(state, merge_label);
|
||||||
const auto value = state.builder.AllocateId();
|
const auto value = state.builder.AllocateId();
|
||||||
state.builder.AddFunction(spv::OpPhi, type, value, then_value, then_exit, default_value,
|
state.builder.AddFunction(spv::OpPhi, type, value, then_value, then_exit, default_value,
|
||||||
else_label);
|
header);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,11 +35,22 @@ struct BufferAddress {
|
|||||||
BufferAddress CalculateBufferAddress(EmitterState& state, uint32_t index, uint32_t offset,
|
BufferAddress CalculateBufferAddress(EmitterState& state, uint32_t index, uint32_t offset,
|
||||||
uint32_t soffset, uint32_t immediate, uint32_t stride,
|
uint32_t soffset, uint32_t immediate, uint32_t stride,
|
||||||
uint32_t swizzle, uint32_t index_stride) {
|
uint32_t swizzle, uint32_t index_stride) {
|
||||||
|
const auto zero = ConstantU32(state, 0);
|
||||||
|
const auto one = ConstantU32(state, 1);
|
||||||
|
const auto add = [&](uint32_t lhs, uint32_t rhs) {
|
||||||
|
return lhs == zero ? rhs : rhs == zero ? lhs
|
||||||
|
: Binary(state, spv::OpIAdd, TypeU32(state), lhs, rhs);
|
||||||
|
};
|
||||||
|
const auto mul = [&](uint32_t lhs, uint32_t rhs) {
|
||||||
|
return lhs == zero || rhs == zero ? zero
|
||||||
|
: lhs == one ? rhs
|
||||||
|
: rhs == one ? lhs
|
||||||
|
: Binary(state, spv::OpIMul, TypeU32(state), lhs, rhs);
|
||||||
|
};
|
||||||
if (immediate != 0u) {
|
if (immediate != 0u) {
|
||||||
offset = Binary(state, spv::OpIAdd, TypeU32(state), offset, ConstantU32(state, immediate));
|
offset = add(offset, ConstantU32(state, immediate));
|
||||||
}
|
}
|
||||||
const auto indexed = Binary(state, spv::OpIMul, TypeU32(state), index, stride);
|
auto address = add(mul(index, stride), offset);
|
||||||
auto address = Binary(state, spv::OpIAdd, TypeU32(state), indexed, offset);
|
|
||||||
if (swizzle != 0u) {
|
if (swizzle != 0u) {
|
||||||
const auto index_shift =
|
const auto index_shift =
|
||||||
Binary(state, spv::OpIAdd, TypeU32(state), index_stride, ConstantU32(state, 3));
|
Binary(state, spv::OpIAdd, TypeU32(state), index_stride, ConstantU32(state, 3));
|
||||||
@@ -54,18 +65,12 @@ BufferAddress CalculateBufferAddress(EmitterState& state, uint32_t index, uint32
|
|||||||
Binary(state, spv::OpBitwiseAnd, TypeU32(state), offset, ConstantU32(state, ~3u));
|
Binary(state, spv::OpBitwiseAnd, TypeU32(state), offset, ConstantU32(state, ~3u));
|
||||||
const auto offset_lsb =
|
const auto offset_lsb =
|
||||||
Binary(state, spv::OpBitwiseAnd, TypeU32(state), offset, ConstantU32(state, 3u));
|
Binary(state, spv::OpBitwiseAnd, TypeU32(state), offset, ConstantU32(state, 3u));
|
||||||
const auto indexed_msb = Binary(state, spv::OpIMul, TypeU32(state), index_msb, stride);
|
const auto msb = mul(add(mul(index_msb, stride), offset_msb), indices);
|
||||||
const auto msb =
|
const auto lsb = add(Binary(state, spv::OpShiftLeftLogical, TypeU32(state), index_lsb,
|
||||||
Binary(state, spv::OpIMul, TypeU32(state),
|
ConstantU32(state, 2u)), offset_lsb);
|
||||||
Binary(state, spv::OpIAdd, TypeU32(state), indexed_msb, offset_msb), indices);
|
address = Select(state, TypeU32(state), swizzle, add(msb, lsb), address);
|
||||||
const auto lsb = Binary(state, spv::OpIAdd, TypeU32(state),
|
|
||||||
Binary(state, spv::OpShiftLeftLogical, TypeU32(state), index_lsb,
|
|
||||||
ConstantU32(state, 2u)),
|
|
||||||
offset_lsb);
|
|
||||||
address = Select(state, TypeU32(state), swizzle,
|
|
||||||
Binary(state, spv::OpIAdd, TypeU32(state), msb, lsb), address);
|
|
||||||
}
|
}
|
||||||
return {offset, Binary(state, spv::OpIAdd, TypeU32(state), address, soffset)};
|
return {offset, add(address, soffset)};
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t BufferLane(EmitterState& state) {
|
uint32_t BufferLane(EmitterState& state) {
|
||||||
|
|||||||
Reference in New Issue
Block a user