Fix DC flush programming in non concurrent scenarios.

-If out of order flag was disabled then pipe control was not having dc flush.
-This could led to a batch buffer that doesn't end with dc flush.
-This change adds differentiation between pipe controls that may be erased and
pipe controls that are used as a part of epilogue command

Change-Id: Ic9c970c75c89ff524a0e40506eff6dd097760145
This commit is contained in:
Mrozek, Michal 2018-02-15 08:29:57 +01:00 committed by sys_ocldev
parent 2d0af9d4a4
commit acb044dce3
6 changed files with 74 additions and 32 deletions

View File

@ -118,6 +118,7 @@ CompletionStamp CommandStreamReceiverHw<GfxFamily>::flushTask(
auto levelClosed = false;
void *currentPipeControlForNooping = nullptr;
void *epiloguePipeControlLocation = nullptr;
Device *device = this->getMemoryManager()->device;
if (dispatchFlags.blocking || dispatchFlags.dcFlush || dispatchFlags.guardCommandBufferWithPipeControl) {
@ -131,8 +132,10 @@ CompletionStamp CommandStreamReceiverHw<GfxFamily>::flushTask(
}
}
epiloguePipeControlLocation = ptrOffset(commandStreamTask.getBase(), commandStreamTask.getUsed());
if (dispatchFlags.outOfOrderExecutionAllowed && !dispatchFlags.dcFlush) {
currentPipeControlForNooping = ptrOffset(commandStreamTask.getBase(), commandStreamTask.getUsed());
currentPipeControlForNooping = epiloguePipeControlLocation;
}
//Some architectures (SKL) requires to have pipe control prior to pipe control with tag write, add it here
@ -343,7 +346,8 @@ CompletionStamp CommandStreamReceiverHw<GfxFamily>::flushTask(
commandBuffer->batchBufferEndLocation = bbEndLocation;
commandBuffer->taskCount = this->taskCount + 1;
commandBuffer->flushStamp->replaceStampObject(dispatchFlags.flushStampReference);
commandBuffer->pipeControlLocation = currentPipeControlForNooping;
commandBuffer->pipeControlThatMayBeErasedLocation = currentPipeControlForNooping;
commandBuffer->epiloguePipeControlLocation = epiloguePipeControlLocation;
this->submissionAggregator->recordCommandBuffer(commandBuffer);
}
} else {
@ -392,7 +396,8 @@ inline void CommandStreamReceiverHw<GfxFamily>::flushBatchedSubmissions() {
ResidencyContainer surfacesForSubmit;
ResourcePackage resourcePackage;
auto pipeControlLocationSize = getRequiredPipeControlSize();
void *currentPipeControl = nullptr;
void *currentPipeControlForNooping = nullptr;
void *epiloguePipeControlLocation = nullptr;
while (!commandBufferList.peekIsEmpty()) {
size_t totalUsedSize = 0u;
@ -405,15 +410,18 @@ inline void CommandStreamReceiverHw<GfxFamily>::flushBatchedSubmissions() {
FlushStampUpdateHelper flushStampUpdateHelper;
flushStampUpdateHelper.insert(primaryCmdBuffer->flushStamp->getStampReference());
currentPipeControl = primaryCmdBuffer->pipeControlLocation;
currentPipeControlForNooping = primaryCmdBuffer->pipeControlThatMayBeErasedLocation;
epiloguePipeControlLocation = primaryCmdBuffer->epiloguePipeControlLocation;
while (nextCommandBuffer && nextCommandBuffer->inspectionId == primaryCmdBuffer->inspectionId) {
//noop pipe control
if (currentPipeControl) {
memset(currentPipeControl, 0, pipeControlLocationSize);
if (currentPipeControlForNooping) {
memset(currentPipeControlForNooping, 0, pipeControlLocationSize);
}
//obtain next candidate for nooping
currentPipeControl = nextCommandBuffer->pipeControlLocation;
currentPipeControlForNooping = nextCommandBuffer->pipeControlThatMayBeErasedLocation;
//track epilogue pipe control
epiloguePipeControlLocation = nextCommandBuffer->epiloguePipeControlLocation;
flushStampUpdateHelper.insert(nextCommandBuffer->flushStamp->getStampReference());
auto nextCommandBufferAddress = nextCommandBuffer->batchBuffer.commandBufferAllocation->getUnderlyingBuffer();
@ -430,9 +438,7 @@ inline void CommandStreamReceiverHw<GfxFamily>::flushBatchedSubmissions() {
}
//make sure we flush DC
if (currentPipeControl) {
((PIPE_CONTROL *)currentPipeControl)->setDcFlushEnable(true);
}
((PIPE_CONTROL *)epiloguePipeControlLocation)->setDcFlushEnable(true);
auto flushStamp = this->flush(primaryCmdBuffer->batchBuffer, engineType, &surfacesForSubmit);

View File

@ -57,7 +57,8 @@ struct CommandBuffer : public IDNode<CommandBuffer> {
void *batchBufferEndLocation = nullptr;
uint32_t inspectionId = 0;
uint32_t taskCount = 0u;
void *pipeControlLocation = nullptr;
void *pipeControlThatMayBeErasedLocation = nullptr;
void *epiloguePipeControlLocation = nullptr;
std::unique_ptr<FlushStampTracker> flushStamp;
};

View File

@ -1416,7 +1416,7 @@ HWTEST_F(EnqueueKernelTest, givenOutOfOrderCommandQueueWhenEnqueueKernelIsMadeTh
EXPECT_FALSE(mockedSubmissionsAggregator->peekCmdBufferList().peekIsEmpty());
auto cmdBuffer = mockedSubmissionsAggregator->peekCmdBufferList().peekHead();
EXPECT_NE(nullptr, cmdBuffer->pipeControlLocation);
EXPECT_NE(nullptr, cmdBuffer->pipeControlThatMayBeErasedLocation);
clReleaseCommandQueue(ooq);
}
@ -1438,7 +1438,7 @@ HWTEST_F(EnqueueKernelTest, givenInOrderCommandQueueWhenEnqueueKernelIsMadeThenP
EXPECT_FALSE(mockedSubmissionsAggregator->peekCmdBufferList().peekIsEmpty());
auto cmdBuffer = mockedSubmissionsAggregator->peekCmdBufferList().peekHead();
EXPECT_NE(nullptr, cmdBuffer->pipeControlLocation);
EXPECT_NE(nullptr, cmdBuffer->pipeControlThatMayBeErasedLocation);
clReleaseCommandQueue(inOrderQueue);
}
@ -1461,7 +1461,8 @@ HWTEST_F(EnqueueKernelTest, givenInOrderCommandQueueWhenEnqueueKernelThatHasShar
EXPECT_FALSE(mockedSubmissionsAggregator->peekCmdBufferList().peekIsEmpty());
auto cmdBuffer = mockedSubmissionsAggregator->peekCmdBufferList().peekHead();
EXPECT_EQ(nullptr, cmdBuffer->pipeControlLocation);
EXPECT_EQ(nullptr, cmdBuffer->pipeControlThatMayBeErasedLocation);
EXPECT_NE(nullptr, cmdBuffer->epiloguePipeControlLocation);
clReleaseCommandQueue(inOrderQueue);
}
@ -1485,7 +1486,8 @@ HWTEST_F(EnqueueKernelTest, givenInOrderCommandQueueWhenEnqueueKernelReturningEv
EXPECT_FALSE(mockedSubmissionsAggregator->peekCmdBufferList().peekIsEmpty());
auto cmdBuffer = mockedSubmissionsAggregator->peekCmdBufferList().peekHead();
EXPECT_EQ(nullptr, cmdBuffer->pipeControlLocation);
EXPECT_EQ(nullptr, cmdBuffer->pipeControlThatMayBeErasedLocation);
EXPECT_NE(nullptr, cmdBuffer->epiloguePipeControlLocation);
clReleaseCommandQueue(inOrderQueue);
clReleaseEvent(event);
@ -1510,7 +1512,8 @@ HWTEST_F(EnqueueKernelTest, givenOutOfOrderCommandQueueWhenEnqueueKernelReturnin
EXPECT_FALSE(mockedSubmissionsAggregator->peekCmdBufferList().peekIsEmpty());
auto cmdBuffer = mockedSubmissionsAggregator->peekCmdBufferList().peekHead();
EXPECT_NE(nullptr, cmdBuffer->pipeControlLocation);
EXPECT_NE(nullptr, cmdBuffer->pipeControlThatMayBeErasedLocation);
EXPECT_EQ(cmdBuffer->epiloguePipeControlLocation, cmdBuffer->pipeControlThatMayBeErasedLocation);
clReleaseCommandQueue(inOrderQueue);
clReleaseEvent(event);

View File

@ -2856,14 +2856,14 @@ HWTEST_F(CommandStreamReceiverFlushTaskTests, givenCsrInBatchingModeWhenTwoTasks
//validate if we recorded ppc positions
auto firstCmdBuffer = mockedSubmissionsAggregator->peekCommandBuffers().peekHead();
EXPECT_NE(nullptr, firstCmdBuffer->pipeControlLocation);
EXPECT_NE(nullptr, firstCmdBuffer->pipeControlThatMayBeErasedLocation);
auto secondCmdBuffer = firstCmdBuffer->next;
EXPECT_NE(nullptr, secondCmdBuffer->pipeControlLocation);
EXPECT_NE(firstCmdBuffer->pipeControlLocation, secondCmdBuffer->pipeControlLocation);
EXPECT_NE(nullptr, secondCmdBuffer->pipeControlThatMayBeErasedLocation);
EXPECT_NE(firstCmdBuffer->pipeControlThatMayBeErasedLocation, secondCmdBuffer->pipeControlThatMayBeErasedLocation);
auto ppc = genCmdCast<typename FamilyType::PIPE_CONTROL *>(firstCmdBuffer->pipeControlLocation);
auto ppc = genCmdCast<typename FamilyType::PIPE_CONTROL *>(firstCmdBuffer->pipeControlThatMayBeErasedLocation);
EXPECT_NE(nullptr, ppc);
auto ppc2 = genCmdCast<typename FamilyType::PIPE_CONTROL *>(secondCmdBuffer->pipeControlLocation);
auto ppc2 = genCmdCast<typename FamilyType::PIPE_CONTROL *>(secondCmdBuffer->pipeControlThatMayBeErasedLocation);
EXPECT_NE(nullptr, ppc2);
//flush needs to bump the taskLevel
@ -2952,6 +2952,36 @@ HWTEST_F(CommandStreamReceiverFlushTaskTests, givenCsrInBatchingModeWhenCommandA
EXPECT_TRUE(pipeControl->getDcFlushEnable());
}
HWTEST_F(CommandStreamReceiverFlushTaskTests, givenCsrInBatchingModeWithOutOfOrderModeFisabledWhenCommandAreSubmittedThenDcFlushIsAdded) {
CommandQueueHw<FamilyType> commandQueue(nullptr, pDevice, 0);
auto &commandStream = commandQueue.getCS(4096u);
auto mockCsr = new MockCsrHw2<FamilyType>(*platformDevices[0]);
pDevice->resetCommandStreamReceiver(mockCsr);
mockCsr->overrideDispatchPolicy(CommandStreamReceiver::DispatchMode::BatchedDispatch);
DispatchFlags dispatchFlags;
dispatchFlags.guardCommandBufferWithPipeControl = true;
dispatchFlags.outOfOrderExecutionAllowed = false;
mockCsr->flushTask(commandStream,
0,
dsh,
ih,
ioh,
ssh,
taskLevel,
dispatchFlags);
parseCommands<FamilyType>(commandStream);
auto itorPipeControl = find<typename FamilyType::PIPE_CONTROL *>(cmdList.begin(), cmdList.end());
auto pipeControl = genCmdCast<typename FamilyType::PIPE_CONTROL *>(*itorPipeControl);
mockCsr->flushBatchedSubmissions();
EXPECT_TRUE(pipeControl->getDcFlushEnable());
}
HWTEST_F(CommandStreamReceiverFlushTaskTests, givenCsrInBatchingModeWhenDcFlushIsRequiredThenPipeControlIsNotRegistredForNooping) {
CommandQueueHw<FamilyType> commandQueue(nullptr, pDevice, 0);
auto &commandStream = commandQueue.getCS(4096u);
@ -2977,9 +3007,9 @@ HWTEST_F(CommandStreamReceiverFlushTaskTests, givenCsrInBatchingModeWhenDcFlushI
taskLevel,
dispatchFlags);
//validate if we recorded ppc positions
auto cmdBuffer = mockedSubmissionsAggregator->peekCommandBuffers().peekHead();
EXPECT_EQ(nullptr, cmdBuffer->pipeControlLocation);
EXPECT_EQ(nullptr, cmdBuffer->pipeControlThatMayBeErasedLocation);
EXPECT_NE(nullptr, cmdBuffer->epiloguePipeControlLocation);
}
HWTEST_F(CommandStreamReceiverFlushTaskTests, givenCsrInBatchingModeAndOoqFlagSetToFalseWhenTwoTasksArePassedWithTheSameLevelThenThereIsPipeControlBetweenThemAfterFlush) {
@ -3023,9 +3053,9 @@ HWTEST_F(CommandStreamReceiverFlushTaskTests, givenCsrInBatchingModeAndOoqFlagSe
//validate if we recorded ppc positions
auto firstCmdBuffer = mockedSubmissionsAggregator->peekCommandBuffers().peekHead();
EXPECT_EQ(nullptr, firstCmdBuffer->pipeControlLocation);
EXPECT_EQ(nullptr, firstCmdBuffer->pipeControlThatMayBeErasedLocation);
auto secondCmdBuffer = firstCmdBuffer->next;
EXPECT_EQ(nullptr, secondCmdBuffer->pipeControlLocation);
EXPECT_EQ(nullptr, secondCmdBuffer->pipeControlThatMayBeErasedLocation);
mockCsr->flushBatchedSubmissions();
@ -3079,9 +3109,9 @@ HWTEST_F(CommandStreamReceiverFlushTaskTests, givenCsrInBatchingModeWhenPipeCont
//validate if we recorded ppc positions
auto firstCmdBuffer = mockedSubmissionsAggregator->peekCommandBuffers().peekHead();
auto ppc1Location = firstCmdBuffer->pipeControlLocation;
auto ppc1Location = firstCmdBuffer->pipeControlThatMayBeErasedLocation;
firstCmdBuffer->pipeControlLocation = nullptr;
firstCmdBuffer->pipeControlThatMayBeErasedLocation = nullptr;
auto ppc = genCmdCast<typename FamilyType::PIPE_CONTROL *>(ppc1Location);
EXPECT_NE(nullptr, ppc);
@ -3153,12 +3183,12 @@ HWTEST_F(CommandStreamReceiverFlushTaskTests, givenCsrInBatchingModeWhenThreeTas
auto secondCmdBuffer = firstCmdBuffer->next;
auto thirdCmdBuffer = firstCmdBuffer->next->next;
EXPECT_NE(nullptr, thirdCmdBuffer->pipeControlLocation);
EXPECT_NE(firstCmdBuffer->pipeControlLocation, thirdCmdBuffer->pipeControlLocation);
EXPECT_NE(nullptr, thirdCmdBuffer->pipeControlThatMayBeErasedLocation);
EXPECT_NE(firstCmdBuffer->pipeControlThatMayBeErasedLocation, thirdCmdBuffer->pipeControlThatMayBeErasedLocation);
auto ppc = genCmdCast<typename FamilyType::PIPE_CONTROL *>(firstCmdBuffer->pipeControlLocation);
auto ppc2 = genCmdCast<typename FamilyType::PIPE_CONTROL *>(secondCmdBuffer->pipeControlLocation);
auto ppc3 = genCmdCast<typename FamilyType::PIPE_CONTROL *>(thirdCmdBuffer->pipeControlLocation);
auto ppc = genCmdCast<typename FamilyType::PIPE_CONTROL *>(firstCmdBuffer->pipeControlThatMayBeErasedLocation);
auto ppc2 = genCmdCast<typename FamilyType::PIPE_CONTROL *>(secondCmdBuffer->pipeControlThatMayBeErasedLocation);
auto ppc3 = genCmdCast<typename FamilyType::PIPE_CONTROL *>(thirdCmdBuffer->pipeControlThatMayBeErasedLocation);
EXPECT_NE(nullptr, ppc2);
EXPECT_NE(nullptr, ppc3);

View File

@ -1004,6 +1004,7 @@ TEST_F(DrmCommandStreamBatchingTests, givenRecordedCommandBufferWhenItIsSubmitte
submittedCommandBuffer.getSpace(4);
DispatchFlags dispatchFlags;
dispatchFlags.guardCommandBufferWithPipeControl = true;
tCsr->flushTask(cs, 0u, cs, cs, cs, cs, 0u, dispatchFlags);
auto &cmdBuffers = mockedSubmissionsAggregator->peekCommandBuffers();

View File

@ -533,6 +533,7 @@ HWTEST_F(WddmCommandStreamMockGdiTest, givenRecordedCommandBufferWhenItIsSubmitt
LinearStream cs(commandBuffer);
DispatchFlags dispatchFlags;
dispatchFlags.guardCommandBufferWithPipeControl = true;
dispatchFlags.requiresCoherency = true;
mockCsr->flushTask(cs, 0u, cs, cs, cs, cs, 0u, dispatchFlags);