Fix encodeMulRegVal() calculation

encodeMulRegVal() makes extensive use of encodeAluAdd().

The following problems are addressed:

* encodeAluAdd() performs an addition and saves the
  calculated result to the first register. Saving the
  result to the first register clears the calculated result.

* An array of MI_MATH buffers is setup prior to performing a
  series of encodeAluAdd()'s where the same registers are
  reused for the calculations. For calculated results to be
  carried over from one encodeAluAdd() operation to subsequent
  encodeAluAdd() operations, the MI_MATH buffer needs to be
  setup per encodeAluAdd().

Create EncodeMath<Family>::addition() to reserve a MI_MATH buffer
and performs the addition by calling encodeAluAdd().
Modify encodeAluAdd() to save calculated result to a third
register. Then, after EncodeMath<Family>::addition() is called
in encodeMulRegVal(), copy the calculated result from the result
register to the first register from the EncodeMath<Family>::addition()
operation. This will allow the calculated value to be carried over
to subsequent addition operations.

Change-Id: I9c6f8362a1ca2f7e3361aaa48d8748dd6ff0f4c8
Signed-off-by: Sebastian Sanchez <sebastian.sanchez@intel.com>
This commit is contained in:
Sebastian Sanchez 2020-02-25 10:23:04 -08:00
parent 8e4e053837
commit 1187eb0375
7 changed files with 88 additions and 25 deletions

View File

@ -49,6 +49,15 @@ struct EncodeStates {
static size_t getAdjustStateComputeModeSize();
};
template <typename GfxFamily>
struct EncodeMath {
using MI_MATH_ALU_INST_INLINE = typename GfxFamily::MI_MATH_ALU_INST_INLINE;
using MI_MATH = typename GfxFamily::MI_MATH;
static uint32_t *commandReserve(CommandContainer &container);
static void addition(CommandContainer &container, uint32_t firstOperandRegister, uint32_t secondOperandRegister, uint32_t finalResultRegister);
};
template <typename GfxFamily>
struct EncodeMathMMIO {
using MI_STORE_REGISTER_MEM = typename GfxFamily::MI_STORE_REGISTER_MEM;
@ -65,7 +74,10 @@ struct EncodeMathMMIO {
static void encodeAluSubStoreCarry(MI_MATH_ALU_INST_INLINE *pAluParam, uint32_t regA, uint32_t regB, uint32_t finalResultRegister);
static void encodeAluAdd(MI_MATH_ALU_INST_INLINE *pAluParam, uint32_t regA, uint32_t regB);
static void encodeAluAdd(MI_MATH_ALU_INST_INLINE *pAluParam,
uint32_t firstOperandRegister,
uint32_t secondOperandRegister,
uint32_t finalResultRegister);
};
template <typename GfxFamily>

View File

@ -58,37 +58,24 @@ uint32_t EncodeStates<Family>::copySamplerState(IndirectHeap *dsh,
template <typename Family>
void EncodeMathMMIO<Family>::encodeMulRegVal(CommandContainer &container, uint32_t offset, uint32_t val, uint64_t dstAddress) {
int logLws = 0;
int addsCount = 0;
int i = val;
while (val >> logLws) {
if (val & (1 << logLws)) {
addsCount++;
}
logLws++;
addsCount++;
}
EncodeSetMMIO<Family>::encodeREG(container, CS_GPR_R0, offset);
EncodeSetMMIO<Family>::encodeIMM(container, CS_GPR_R1, 0);
uint32_t length = NUM_ALU_INST_FOR_READ_MODIFY_WRITE * addsCount;
auto cmd2 = reinterpret_cast<uint32_t *>(container.getCommandStream()->getSpace(sizeof(MI_MATH) + sizeof(MI_MATH_ALU_INST_INLINE) * length));
reinterpret_cast<MI_MATH *>(cmd2)->DW0.Value = 0x0;
reinterpret_cast<MI_MATH *>(cmd2)->DW0.BitField.InstructionType = MI_MATH::COMMAND_TYPE_MI_COMMAND;
reinterpret_cast<MI_MATH *>(cmd2)->DW0.BitField.InstructionOpcode = MI_MATH::MI_COMMAND_OPCODE_MI_MATH;
reinterpret_cast<MI_MATH *>(cmd2)->DW0.BitField.DwordLength = length - 1;
cmd2++;
MI_MATH_ALU_INST_INLINE *pAluParam = reinterpret_cast<MI_MATH_ALU_INST_INLINE *>(cmd2);
i = 0;
while (i < logLws) {
if (val & (1 << i)) {
encodeAluAdd(pAluParam, ALU_REGISTER_R_1, ALU_REGISTER_R_0);
pAluParam += NUM_ALU_INST_FOR_READ_MODIFY_WRITE;
EncodeMath<Family>::addition(container, ALU_REGISTER_R_1,
ALU_REGISTER_R_0, ALU_REGISTER_R_2);
EncodeSetMMIO<Family>::encodeREG(container, CS_GPR_R1, CS_GPR_R2);
}
encodeAluAdd(pAluParam, ALU_REGISTER_R_0, ALU_REGISTER_R_0);
pAluParam += NUM_ALU_INST_FOR_READ_MODIFY_WRITE;
EncodeMath<Family>::addition(container, ALU_REGISTER_R_0,
ALU_REGISTER_R_0, ALU_REGISTER_R_2);
EncodeSetMMIO<Family>::encodeREG(container, CS_GPR_R0, CS_GPR_R2);
i++;
}
EncodeStoreMMIO<Family>::encode(container, CS_GPR_R1, dstAddress);
@ -165,8 +152,39 @@ void EncodeMathMMIO<Family>::encodeAluSubStoreCarry(MI_MATH_ALU_INST_INLINE *pAl
}
template <typename Family>
void EncodeMathMMIO<Family>::encodeAluAdd(MI_MATH_ALU_INST_INLINE *pAluParam, uint32_t regA, uint32_t regB) {
encodeAlu(pAluParam, regA, regB, ALU_OPCODE_ADD, regA, ALU_REGISTER_R_ACCU);
uint32_t *EncodeMath<Family>::commandReserve(CommandContainer &container) {
size_t size = sizeof(MI_MATH) + sizeof(MI_MATH_ALU_INST_INLINE) * NUM_ALU_INST_FOR_READ_MODIFY_WRITE;
auto cmd = reinterpret_cast<uint32_t *>(container.getCommandStream()->getSpace(size));
reinterpret_cast<MI_MATH *>(cmd)->DW0.Value = 0x0;
reinterpret_cast<MI_MATH *>(cmd)->DW0.BitField.InstructionType = MI_MATH::COMMAND_TYPE_MI_COMMAND;
reinterpret_cast<MI_MATH *>(cmd)->DW0.BitField.InstructionOpcode = MI_MATH::MI_COMMAND_OPCODE_MI_MATH;
reinterpret_cast<MI_MATH *>(cmd)->DW0.BitField.DwordLength = NUM_ALU_INST_FOR_READ_MODIFY_WRITE - 1;
cmd++;
return cmd;
}
template <typename Family>
void EncodeMath<Family>::addition(CommandContainer &container,
uint32_t firstOperandRegister,
uint32_t secondOperandRegister,
uint32_t finalResultRegister) {
uint32_t *cmd = EncodeMath<Family>::commandReserve(container);
EncodeMath<Family>::MI_MATH_ALU_INST_INLINE *pAluParam =
reinterpret_cast<MI_MATH_ALU_INST_INLINE *>(cmd);
EncodeMathMMIO<Family>::encodeAluAdd(pAluParam, firstOperandRegister,
secondOperandRegister,
finalResultRegister);
}
template <typename Family>
void EncodeMathMMIO<Family>::encodeAluAdd(MI_MATH_ALU_INST_INLINE *pAluParam,
uint32_t firstOperandRegister,
uint32_t secondOperandRegister,
uint32_t finalResultRegister) {
encodeAlu(pAluParam, firstOperandRegister, secondOperandRegister, ALU_OPCODE_ADD, finalResultRegister, ALU_REGISTER_R_ACCU);
}
template <typename Family>

View File

@ -17,6 +17,7 @@ using Family = ICLFamily;
template struct EncodeDispatchKernel<Family>;
template struct EncodeStates<Family>;
template struct EncodeMath<Family>;
template struct EncodeMathMMIO<Family>;
template struct EncodeIndirectParams<Family>;
template struct EncodeSetMMIO<Family>;

View File

@ -37,6 +37,7 @@ size_t EncodeStates<Family>::getAdjustStateComputeModeSize() {
template struct EncodeDispatchKernel<Family>;
template struct EncodeStates<Family>;
template struct EncodeMath<Family>;
template struct EncodeMathMMIO<Family>;
template struct EncodeIndirectParams<Family>;
template struct EncodeSetMMIO<Family>;

View File

@ -18,6 +18,7 @@ using Family = BDWFamily;
template struct EncodeDispatchKernel<Family>;
template struct EncodeStates<Family>;
template struct EncodeMath<Family>;
template struct EncodeMathMMIO<Family>;
template struct EncodeIndirectParams<Family>;
template struct EncodeSetMMIO<Family>;

View File

@ -18,6 +18,7 @@ using Family = SKLFamily;
template struct EncodeDispatchKernel<Family>;
template struct EncodeStates<Family>;
template struct EncodeMath<Family>;
template struct EncodeMathMMIO<Family>;
template struct EncodeIndirectParams<Family>;
template struct EncodeSetMMIO<Family>;

View File

@ -22,10 +22,12 @@ HWTEST_F(EncodeMathMMIOTest, encodeAluAddHasCorrectOpcodesOperands) {
MI_MATH_ALU_INST_INLINE aluParam[5];
uint32_t regA = ALU_REGISTER_R_0;
uint32_t regB = ALU_REGISTER_R_1;
uint32_t finalResultRegister = ALU_REGISTER_R_2;
memset(aluParam, 0, sizeof(MI_MATH_ALU_INST_INLINE) * 5);
EncodeMathMMIO<FamilyType>::encodeAluAdd(aluParam, regA, regB);
EncodeMathMMIO<FamilyType>::encodeAluAdd(aluParam, regA, regB,
finalResultRegister);
EXPECT_EQ(aluParam[0].DW0.BitField.ALUOpcode, ALU_OPCODE_LOAD);
EXPECT_EQ(aluParam[0].DW0.BitField.Operand1, ALU_REGISTER_R_SRCA);
@ -40,7 +42,7 @@ HWTEST_F(EncodeMathMMIOTest, encodeAluAddHasCorrectOpcodesOperands) {
EXPECT_EQ(aluParam[2].DW0.BitField.Operand2, 0u);
EXPECT_EQ(aluParam[3].DW0.BitField.ALUOpcode, ALU_OPCODE_STORE);
EXPECT_EQ(aluParam[3].DW0.BitField.Operand1, ALU_REGISTER_R_0);
EXPECT_EQ(aluParam[3].DW0.BitField.Operand1, ALU_REGISTER_R_2);
EXPECT_EQ(aluParam[3].DW0.BitField.Operand2, ALU_REGISTER_R_ACCU);
EXPECT_EQ(aluParam[4].DW0.Value, 0u);
@ -80,6 +82,33 @@ HWTEST_F(EncodeMathMMIOTest, encodeAluSubStoreCarryHasCorrectOpcodesOperands) {
using CommandEncoderMathTest = Test<DeviceFixture>;
HWTEST_F(CommandEncoderMathTest, commandReserve) {
using MI_MATH = typename FamilyType::MI_MATH;
GenCmdList commands;
CommandContainer cmdContainer;
cmdContainer.initialize(pDevice);
EncodeMath<FamilyType>::commandReserve(cmdContainer);
CmdParse<FamilyType>::parseCommandBuffer(commands,
ptrOffset(cmdContainer.getCommandStream()->getCpuBase(), 0),
cmdContainer.getCommandStream()->getUsed());
auto itor = commands.begin();
itor = find<MI_MATH *>(itor, commands.end());
ASSERT_NE(itor, commands.end());
auto cmdMATH = genCmdCast<MI_MATH *>(*itor);
EXPECT_EQ(cmdMATH->DW0.BitField.InstructionType,
static_cast<uint32_t>(MI_MATH::COMMAND_TYPE_MI_COMMAND));
EXPECT_EQ(cmdMATH->DW0.BitField.InstructionOpcode,
static_cast<uint32_t>(MI_MATH::MI_COMMAND_OPCODE_MI_MATH));
EXPECT_EQ(cmdMATH->DW0.BitField.DwordLength,
static_cast<uint32_t>(NUM_ALU_INST_FOR_READ_MODIFY_WRITE - 1));
}
HWTEST_F(CommandEncoderMathTest, appendsAGreaterThanPredicate) {
using MI_LOAD_REGISTER_MEM = typename FamilyType::MI_LOAD_REGISTER_MEM;
using MI_LOAD_REGISTER_IMM = typename FamilyType::MI_LOAD_REGISTER_IMM;