Fix heap programming in blocked scenarios.
- When command queue is blocked, all heaps are being stored in temporary allocations, command buffers are being pre-programmed, heaps are being set on those temporary allocations with the assumption that all heaps start with offset 0. - Problem was when the actual submissions happened, all those temporary heaps were just copied to appended command queue heaps, so when something was there then new stuff was copied right after it. It means that all state was incorrect as the offsets are not valid anymore and will point to wrong location. - This change releases command queue heaps when blocked command is being submitted to make sure they will be programmed with the proper offset in newly allocate command queue heap. Change-Id: I3e30be13caf4df8621ddb18f8448ffaf0f1278d1
This commit is contained in:
parent
a8b91c8c99
commit
57137fea84
|
@ -151,6 +151,14 @@ CompletionStamp &CommandComputeKernel::submit(uint32_t taskLevel, bool terminate
|
|||
IndirectHeap *dsh = nullptr;
|
||||
IndirectHeap *ioh = nullptr;
|
||||
|
||||
IndirectHeap::Type trackedHeaps[] = {IndirectHeap::SURFACE_STATE, IndirectHeap::INDIRECT_OBJECT, IndirectHeap::DYNAMIC_STATE, IndirectHeap::INSTRUCTION};
|
||||
|
||||
for (auto trackedHeap = 0u; trackedHeap < ARRAY_COUNT(trackedHeaps); trackedHeap++) {
|
||||
if (commandQueue.getIndirectHeap(trackedHeaps[trackedHeap], 0).getUsed() > 0) {
|
||||
commandQueue.releaseIndirectHeap(trackedHeaps[trackedHeap]);
|
||||
}
|
||||
}
|
||||
|
||||
if (executionModelKernel) {
|
||||
dsh = devQueue->getIndirectHeap(IndirectHeap::DYNAMIC_STATE);
|
||||
// In ExecutionModel IOH is the same as DSH to eliminate StateBaseAddress reprogramming for scheduler kernel and blocks.
|
||||
|
@ -158,9 +166,6 @@ CompletionStamp &CommandComputeKernel::submit(uint32_t taskLevel, bool terminate
|
|||
|
||||
memcpy_s(dsh->getSpace(0), dsh->getAvailableSpace(), ptrOffset(kernelOperation->dsh->getBase(), devQueue->colorCalcStateSize), kernelOperation->dsh->getUsed() - devQueue->colorCalcStateSize);
|
||||
dsh->getSpace(kernelOperation->dsh->getUsed() - devQueue->colorCalcStateSize);
|
||||
|
||||
if (commandQueue.getIndirectHeap(IndirectHeap::SURFACE_STATE, 0).getUsed() > 0)
|
||||
commandQueue.releaseIndirectHeap(IndirectHeap::SURFACE_STATE);
|
||||
} else {
|
||||
dsh = &commandQueue.getIndirectHeap(IndirectHeap::DYNAMIC_STATE, requestedDshSize);
|
||||
ioh = &commandQueue.getIndirectHeap(IndirectHeap::INDIRECT_OBJECT, requestedIohSize);
|
||||
|
|
|
@ -348,6 +348,69 @@ HWTEST_F(CommandQueueHwTest, GivenNotCompleteUserEventPassedToEnqueueWhenEventIs
|
|||
mockCSR->getMemoryManager()->freeGraphicsMemory(printfSurface);
|
||||
mockCSR->getMemoryManager()->freeGraphicsMemory(constantSurface);
|
||||
}
|
||||
typedef CommandQueueHwTest BlockedCommandQueueTest;
|
||||
HWTEST_F(BlockedCommandQueueTest, givenCommandQueueWhichHasSomeUsedHeapsWhenBlockedCommandIsBeingSubmittedItReloadsThemToZeroToKeepProperOffsets) {
|
||||
UserEvent userEvent(context);
|
||||
MockKernelWithInternals mockKernelWithInternals(*pDevice);
|
||||
auto mockKernel = mockKernelWithInternals.mockKernel;
|
||||
|
||||
size_t offset = 0;
|
||||
size_t size = 1;
|
||||
|
||||
cl_event blockedEvent = &userEvent;
|
||||
|
||||
auto &ish = pCmdQ->getIndirectHeap(IndirectHeap::INSTRUCTION, 4096u);
|
||||
auto &ioh = pCmdQ->getIndirectHeap(IndirectHeap::INDIRECT_OBJECT, 4096u);
|
||||
auto &dsh = pCmdQ->getIndirectHeap(IndirectHeap::DYNAMIC_STATE, 4096u);
|
||||
auto &ssh = pCmdQ->getIndirectHeap(IndirectHeap::SURFACE_STATE, 4096u);
|
||||
|
||||
ssh.getSpace(1);
|
||||
ish.getSpace(1);
|
||||
ioh.getSpace(1);
|
||||
dsh.getSpace(1);
|
||||
|
||||
auto ishBase = ish.getBase();
|
||||
auto iohBase = ioh.getBase();
|
||||
auto dshBase = dsh.getBase();
|
||||
auto sshBase = ssh.getBase();
|
||||
|
||||
pCmdQ->enqueueKernel(mockKernel, 1, &offset, &size, &size, 1, &blockedEvent, nullptr);
|
||||
userEvent.setStatus(CL_COMPLETE);
|
||||
|
||||
EXPECT_NE(ishBase, ish.getBase());
|
||||
EXPECT_NE(iohBase, ioh.getBase());
|
||||
EXPECT_NE(dshBase, dsh.getBase());
|
||||
EXPECT_NE(sshBase, ssh.getBase());
|
||||
}
|
||||
|
||||
HWTEST_F(BlockedCommandQueueTest, givenCommandQueueWhichHasSomeUnusedHeapsWhenBlockedCommandIsBeingSubmittedThenThoseHeapsAreBeingUsed) {
|
||||
UserEvent userEvent(context);
|
||||
MockKernelWithInternals mockKernelWithInternals(*pDevice);
|
||||
auto mockKernel = mockKernelWithInternals.mockKernel;
|
||||
|
||||
size_t offset = 0;
|
||||
size_t size = 1;
|
||||
|
||||
cl_event blockedEvent = &userEvent;
|
||||
|
||||
auto &ish = pCmdQ->getIndirectHeap(IndirectHeap::INSTRUCTION, 4096u);
|
||||
auto &ioh = pCmdQ->getIndirectHeap(IndirectHeap::INDIRECT_OBJECT, 4096u);
|
||||
auto &dsh = pCmdQ->getIndirectHeap(IndirectHeap::DYNAMIC_STATE, 4096u);
|
||||
auto &ssh = pCmdQ->getIndirectHeap(IndirectHeap::SURFACE_STATE, 4096u);
|
||||
|
||||
auto ishBase = ish.getBase();
|
||||
auto iohBase = ioh.getBase();
|
||||
auto dshBase = dsh.getBase();
|
||||
auto sshBase = ssh.getBase();
|
||||
|
||||
pCmdQ->enqueueKernel(mockKernel, 1, &offset, &size, &size, 1, &blockedEvent, nullptr);
|
||||
userEvent.setStatus(CL_COMPLETE);
|
||||
|
||||
EXPECT_EQ(ishBase, ish.getBase());
|
||||
EXPECT_EQ(iohBase, ioh.getBase());
|
||||
EXPECT_EQ(dshBase, dsh.getBase());
|
||||
EXPECT_EQ(sshBase, ssh.getBase());
|
||||
}
|
||||
|
||||
typedef CommandQueueHwTest CommandQueueHwRefCountTest;
|
||||
|
||||
|
|
Loading…
Reference in New Issue