[SPIR-V] Scalar kill instructions

This commit is contained in:
Triang3l 2020-11-01 22:22:34 +03:00
parent 7512560416
commit cb35aaf13b
1 changed files with 40 additions and 7 deletions

View File

@ -997,11 +997,11 @@ spv::Id SpirvShaderTranslator::ProcessScalarAluOperation(
static_cast<unsigned int>(spv::OpNop), // kSetpPop
static_cast<unsigned int>(spv::OpNop), // kSetpClr
static_cast<unsigned int>(spv::OpNop), // kSetpRstr
static_cast<unsigned int>(spv::OpNop), // kKillsEq
static_cast<unsigned int>(spv::OpNop), // kKillsGt
static_cast<unsigned int>(spv::OpNop), // kKillsGe
static_cast<unsigned int>(spv::OpNop), // kKillsNe
static_cast<unsigned int>(spv::OpNop), // kKillsOne
static_cast<unsigned int>(spv::OpFOrdEqual), // kKillsEq
static_cast<unsigned int>(spv::OpFOrdGreaterThan), // kKillsGt
static_cast<unsigned int>(spv::OpFOrdGreaterThanEqual), // kKillsGe
static_cast<unsigned int>(spv::OpFUnordNotEqual), // kKillsNe
static_cast<unsigned int>(spv::OpFOrdEqual), // kKillsOne
static_cast<unsigned int>(GLSLstd450Sqrt), // kSqrt
static_cast<unsigned int>(spv::OpNop), // Invalid
static_cast<unsigned int>(spv::OpNop), // kMulsc0
@ -1043,8 +1043,8 @@ spv::Id SpirvShaderTranslator::ProcessScalarAluOperation(
if (a != b) {
// Shader Model 3: +0 or denormal * anything = +-0.
result = ZeroIfAnyOperandIsZero(
result, GetAbsoluteOperand(a, instr.vector_operands[0]),
GetAbsoluteOperand(b, instr.vector_operands[0]));
result, GetAbsoluteOperand(a, instr.scalar_operands[0]),
GetAbsoluteOperand(b, instr.scalar_operands[0]));
}
return result;
}
@ -1400,6 +1400,39 @@ spv::Id SpirvShaderTranslator::ProcessScalarAluOperation(
const_float_0_, a);
}
case ucode::AluScalarOpcode::kKillsEq:
case ucode::AluScalarOpcode::kKillsGt:
case ucode::AluScalarOpcode::kKillsGe:
case ucode::AluScalarOpcode::kKillsNe:
case ucode::AluScalarOpcode::kKillsOne: {
// Selection merge must be the penultimate instruction in the block, check
// the condition before it.
spv::Id condition = builder_->createBinOp(
spv::Op(kOps[size_t(instr.scalar_opcode)]), type_bool_,
GetOperandComponents(operand_storage[0], instr.scalar_operands[0],
0b0001),
instr.scalar_opcode == ucode::AluScalarOpcode::kKillsOne
? const_float_1_
: const_float_0_);
spv::Block& kill_block = builder_->makeNewBlock();
spv::Block& merge_block = builder_->makeNewBlock();
{
std::unique_ptr<spv::Instruction> selection_merge_op =
std::make_unique<spv::Instruction>(spv::OpSelectionMerge);
selection_merge_op->addIdOperand(merge_block.getId());
selection_merge_op->addImmediateOperand(spv::SelectionControlMaskNone);
builder_->getBuildPoint()->addInstruction(
std::move(selection_merge_op));
}
builder_->createConditionalBranch(condition, &kill_block, &merge_block);
builder_->setBuildPoint(&kill_block);
// TODO(Triang3l): Demote to helper invocation to keep derivatives if
// needed (and return 1 if killed in this case).
builder_->createNoResultOp(spv::OpKill);
builder_->setBuildPoint(&merge_block);
return const_float_0_;
}
// TODO(Triang3l): Implement the rest of instructions.
}