mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 10:56:58 +02:00
refactor(shader): emit SPIR-V declarations on demand
This commit is contained in:
@@ -3,10 +3,7 @@
|
||||
namespace Libs::Graphics::ShaderRecompiler::Spirv::Emitter {
|
||||
|
||||
uint32_t EmitTrueBool(EmitterState& state) {
|
||||
const auto ret = state.builder.AllocateId();
|
||||
state.builder.AddFunction(
|
||||
{OpINotEqual, state.bool_type, ret, ConstantU32(state, 1), ConstantU32(state, 0)});
|
||||
return ret;
|
||||
return ConstantBool(state, true);
|
||||
}
|
||||
|
||||
DppTargetLane EmitDppQuadPermTargetLane(EmitterState& state, uint32_t subid, uint32_t control) {
|
||||
@@ -17,15 +14,15 @@ DppTargetLane EmitDppQuadPermTargetLane(EmitterState& state, uint32_t subid, uin
|
||||
const auto selected = state.builder.AllocateId();
|
||||
const auto target = state.builder.AllocateId();
|
||||
state.builder.AddFunction(
|
||||
{OpBitwiseAnd, state.uint_type, quad_base, subid, ConstantU32(state, 0xfffffffcu)});
|
||||
state.builder.AddFunction({OpBitwiseAnd, state.uint_type, lane, subid, ConstantU32(state, 3)});
|
||||
{OpBitwiseAnd, TypeU32(state), quad_base, subid, ConstantU32(state, 0xfffffffcu)});
|
||||
state.builder.AddFunction({OpBitwiseAnd, TypeU32(state), lane, subid, ConstantU32(state, 3)});
|
||||
state.builder.AddFunction(
|
||||
{OpShiftLeftLogical, state.uint_type, shift, lane, ConstantU32(state, 1)});
|
||||
{OpShiftLeftLogical, TypeU32(state), shift, lane, ConstantU32(state, 1)});
|
||||
state.builder.AddFunction(
|
||||
{OpShiftRightLogical, state.uint_type, selected0, ConstantU32(state, control), shift});
|
||||
{OpShiftRightLogical, TypeU32(state), selected0, ConstantU32(state, control), shift});
|
||||
state.builder.AddFunction(
|
||||
{OpBitwiseAnd, state.uint_type, selected, selected0, ConstantU32(state, 3)});
|
||||
state.builder.AddFunction({OpBitwiseOr, state.uint_type, target, quad_base, selected});
|
||||
{OpBitwiseAnd, TypeU32(state), selected, selected0, ConstantU32(state, 3)});
|
||||
state.builder.AddFunction({OpBitwiseOr, TypeU32(state), target, quad_base, selected});
|
||||
return {target, EmitTrueBool(state)};
|
||||
}
|
||||
|
||||
@@ -37,20 +34,20 @@ DppTargetLane EmitDppRowShiftTargetLane(EmitterState& state, uint32_t subid, uin
|
||||
const auto target = state.builder.AllocateId();
|
||||
const auto valid = state.builder.AllocateId();
|
||||
state.builder.AddFunction(
|
||||
{OpBitwiseAnd, state.uint_type, row, subid, ConstantU32(state, 0xfffffff0u)});
|
||||
state.builder.AddFunction({OpBitwiseAnd, state.uint_type, lane, subid, ConstantU32(state, 15)});
|
||||
{OpBitwiseAnd, TypeU32(state), row, subid, ConstantU32(state, 0xfffffff0u)});
|
||||
state.builder.AddFunction({OpBitwiseAnd, TypeU32(state), lane, subid, ConstantU32(state, 15)});
|
||||
if (left) {
|
||||
state.builder.AddFunction(
|
||||
{OpIAdd, state.uint_type, lane_shifted, lane, ConstantU32(state, amount)});
|
||||
{OpIAdd, TypeU32(state), lane_shifted, lane, ConstantU32(state, amount)});
|
||||
state.builder.AddFunction(
|
||||
{OpULessThan, state.bool_type, valid, lane, ConstantU32(state, 16u - amount)});
|
||||
{OpULessThan, TypeBool(state), valid, lane, ConstantU32(state, 16u - amount)});
|
||||
} else {
|
||||
state.builder.AddFunction(
|
||||
{OpISub, state.uint_type, lane_shifted, lane, ConstantU32(state, amount)});
|
||||
{OpISub, TypeU32(state), lane_shifted, lane, ConstantU32(state, amount)});
|
||||
state.builder.AddFunction(
|
||||
{OpUGreaterThanEqual, state.bool_type, valid, lane, ConstantU32(state, amount)});
|
||||
{OpUGreaterThanEqual, TypeBool(state), valid, lane, ConstantU32(state, amount)});
|
||||
}
|
||||
state.builder.AddFunction({OpBitwiseOr, state.uint_type, target, row, lane_shifted});
|
||||
state.builder.AddFunction({OpBitwiseOr, TypeU32(state), target, row, lane_shifted});
|
||||
return {target, valid};
|
||||
}
|
||||
|
||||
@@ -64,15 +61,15 @@ DppTargetLane EmitDppRowRotateRightTargetLane(EmitterState& state, uint32_t subi
|
||||
const auto selected = state.builder.AllocateId();
|
||||
const auto target = state.builder.AllocateId();
|
||||
state.builder.AddFunction(
|
||||
{OpBitwiseAnd, state.uint_type, row, subid, ConstantU32(state, 0xfffffff0u)});
|
||||
state.builder.AddFunction({OpBitwiseAnd, state.uint_type, lane, subid, ConstantU32(state, 15)});
|
||||
{OpBitwiseAnd, TypeU32(state), row, subid, ConstantU32(state, 0xfffffff0u)});
|
||||
state.builder.AddFunction({OpBitwiseAnd, TypeU32(state), lane, subid, ConstantU32(state, 15)});
|
||||
state.builder.AddFunction(
|
||||
{OpUGreaterThanEqual, state.bool_type, in_high, lane, ConstantU32(state, amount)});
|
||||
state.builder.AddFunction({OpISub, state.uint_type, minus, lane, ConstantU32(state, amount)});
|
||||
{OpUGreaterThanEqual, TypeBool(state), in_high, lane, ConstantU32(state, amount)});
|
||||
state.builder.AddFunction({OpISub, TypeU32(state), minus, lane, ConstantU32(state, amount)});
|
||||
state.builder.AddFunction(
|
||||
{OpIAdd, state.uint_type, plus, lane, ConstantU32(state, 16u - amount)});
|
||||
state.builder.AddFunction({OpSelect, state.uint_type, selected, in_high, minus, plus});
|
||||
state.builder.AddFunction({OpBitwiseOr, state.uint_type, target, row, selected});
|
||||
{OpIAdd, TypeU32(state), plus, lane, ConstantU32(state, 16u - amount)});
|
||||
state.builder.AddFunction({OpSelect, TypeU32(state), selected, in_high, minus, plus});
|
||||
state.builder.AddFunction({OpBitwiseOr, TypeU32(state), target, row, selected});
|
||||
return {target, EmitTrueBool(state)};
|
||||
}
|
||||
|
||||
@@ -84,12 +81,12 @@ DppTargetLane EmitDppMirrorTargetLane(EmitterState& state, uint32_t subid, bool
|
||||
const auto mirrored = state.builder.AllocateId();
|
||||
const auto target = state.builder.AllocateId();
|
||||
state.builder.AddFunction(
|
||||
{OpBitwiseAnd, state.uint_type, base, subid, ConstantU32(state, base_mask)});
|
||||
{OpBitwiseAnd, TypeU32(state), base, subid, ConstantU32(state, base_mask)});
|
||||
state.builder.AddFunction(
|
||||
{OpBitwiseAnd, state.uint_type, lane, subid, ConstantU32(state, lane_mask)});
|
||||
{OpBitwiseAnd, TypeU32(state), lane, subid, ConstantU32(state, lane_mask)});
|
||||
state.builder.AddFunction(
|
||||
{OpISub, state.uint_type, mirrored, ConstantU32(state, lane_mask), lane});
|
||||
state.builder.AddFunction({OpBitwiseOr, state.uint_type, target, base, mirrored});
|
||||
{OpISub, TypeU32(state), mirrored, ConstantU32(state, lane_mask), lane});
|
||||
state.builder.AddFunction({OpBitwiseOr, TypeU32(state), target, base, mirrored});
|
||||
return {target, EmitTrueBool(state)};
|
||||
}
|
||||
|
||||
@@ -122,7 +119,7 @@ uint32_t EmitSubgroupLocalInvocationId(EmitterState& state) {
|
||||
}
|
||||
const auto value = state.builder.AllocateId();
|
||||
state.builder.AddFunction(
|
||||
{OpLoad, state.uint_type, value, state.subgroup_local_invocation_id_variable});
|
||||
{OpLoad, TypeU32(state), value, state.subgroup_local_invocation_id_variable});
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -151,9 +148,9 @@ uint32_t EmitInputComponentU32(EmitterState& state, IR::StageInputKind kind, uin
|
||||
}
|
||||
const auto pointer = state.builder.AllocateId();
|
||||
const auto value = state.builder.AllocateId();
|
||||
state.builder.AddFunction(
|
||||
{OpAccessChain, state.ptr_input_uint, pointer, variable, ConstantU32(state, component)});
|
||||
state.builder.AddFunction({OpLoad, state.uint_type, value, pointer});
|
||||
state.builder.AddFunction({OpAccessChain, TypePointer(state, StorageClassInput, TypeU32(state)),
|
||||
pointer, variable, ConstantU32(state, component)});
|
||||
state.builder.AddFunction({OpLoad, TypeU32(state), value, pointer});
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -163,7 +160,7 @@ uint32_t EmitLocalInvocationIndex(EmitterState& state) {
|
||||
return ConstantU32(state, 0);
|
||||
}
|
||||
const auto value = state.builder.AllocateId();
|
||||
state.builder.AddFunction({OpLoad, state.uint_type, value, variable});
|
||||
state.builder.AddFunction({OpLoad, TypeU32(state), value, variable});
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -200,47 +197,47 @@ uint32_t EmitVertexParameterComponentU32(EmitterState& state, const InputBinding
|
||||
}
|
||||
|
||||
const auto bits = state.builder.AllocateId();
|
||||
state.builder.AddFunction({OpBitcast, state.uint_type, bits, raw});
|
||||
state.builder.AddFunction({OpBitcast, TypeU32(state), bits, raw});
|
||||
return bits;
|
||||
}
|
||||
|
||||
uint32_t EmitSubgroupLaneActiveBool(EmitterState& state, uint32_t lane) {
|
||||
const auto active_ballot = state.builder.AllocateId();
|
||||
state.builder.AddFunction({OpGroupNonUniformBallot, state.vec4_uint_type, active_ballot,
|
||||
state.builder.AddFunction({OpGroupNonUniformBallot, TypeU32Vector(state, 4), active_ballot,
|
||||
ConstantU32(state, ScopeSubgroup), EmitTrueBool(state)});
|
||||
return EmitBallotLaneActiveBool(state, active_ballot, lane);
|
||||
}
|
||||
uint32_t EmitBallotLaneActiveBool(EmitterState& state, uint32_t active_ballot, uint32_t lane) {
|
||||
const auto low = state.builder.AllocateId();
|
||||
state.builder.AddFunction({OpCompositeExtract, state.uint_type, low, active_ballot, 0});
|
||||
state.builder.AddFunction({OpCompositeExtract, TypeU32(state), low, active_ballot, 0});
|
||||
uint32_t mask = low;
|
||||
if (state.wave_size == 64u) {
|
||||
const auto high = state.builder.AllocateId();
|
||||
const auto in_high = state.builder.AllocateId();
|
||||
const auto selected = state.builder.AllocateId();
|
||||
state.builder.AddFunction({OpCompositeExtract, state.uint_type, high, active_ballot, 1});
|
||||
state.builder.AddFunction({OpCompositeExtract, TypeU32(state), high, active_ballot, 1});
|
||||
state.builder.AddFunction(
|
||||
{OpUGreaterThanEqual, state.bool_type, in_high, lane, ConstantU32(state, 32)});
|
||||
state.builder.AddFunction({OpSelect, state.uint_type, selected, in_high, high, low});
|
||||
{OpUGreaterThanEqual, TypeBool(state), in_high, lane, ConstantU32(state, 32)});
|
||||
state.builder.AddFunction({OpSelect, TypeU32(state), selected, in_high, high, low});
|
||||
mask = selected;
|
||||
}
|
||||
|
||||
const auto lane_low = state.builder.AllocateId();
|
||||
const auto bit = state.builder.AllocateId();
|
||||
state.builder.AddFunction(
|
||||
{OpBitwiseAnd, state.uint_type, lane_low, lane, ConstantU32(state, 31)});
|
||||
{OpBitwiseAnd, TypeU32(state), lane_low, lane, ConstantU32(state, 31)});
|
||||
state.builder.AddFunction(
|
||||
{OpShiftLeftLogical, state.uint_type, bit, ConstantU32(state, 1), lane_low});
|
||||
{OpShiftLeftLogical, TypeU32(state), bit, ConstantU32(state, 1), lane_low});
|
||||
|
||||
const auto hit = state.builder.AllocateId();
|
||||
const auto active = state.builder.AllocateId();
|
||||
const auto in_range = state.builder.AllocateId();
|
||||
const auto ret = state.builder.AllocateId();
|
||||
state.builder.AddFunction({OpBitwiseAnd, state.uint_type, hit, mask, bit});
|
||||
state.builder.AddFunction({OpINotEqual, state.bool_type, active, hit, ConstantU32(state, 0)});
|
||||
state.builder.AddFunction({OpBitwiseAnd, TypeU32(state), hit, mask, bit});
|
||||
state.builder.AddFunction({OpINotEqual, TypeBool(state), active, hit, ConstantU32(state, 0)});
|
||||
state.builder.AddFunction(
|
||||
{OpULessThan, state.bool_type, in_range, lane, ConstantU32(state, state.wave_size)});
|
||||
state.builder.AddFunction({OpLogicalAnd, state.bool_type, ret, active, in_range});
|
||||
{OpULessThan, TypeBool(state), in_range, lane, ConstantU32(state, state.wave_size)});
|
||||
state.builder.AddFunction({OpLogicalAnd, TypeBool(state), ret, active, in_range});
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user