Hi Marcel, Thanks for your help.
- I wrote above “…calling DxgkCbNotifyInterrupt and DxgkCbQueueDpc AT THE APPROPRIATE ELEVATED INTERRUPT LEVEL” which is DIRQL. DxgkDdiSubmitCommand only runs on IRQL_DISPATCH_LEVEL. VirtualBox WDDM driver source code clearly shows how to do this using DxgkCbSynchronizeExecution.
OK, I have modified it. Thanks. I didn’t know about INTERRUPT LEVEL until you told me…HOHO~
2.a. There is nothing wrong with 0 == pPresent->pAllocationList[DXGK_PRESENT_SOURCE_INDEX].SegmentId. This is a standard situation. This means that the source allocation is not available yet. It still has to be paged in by video memory manager before it can be used. It will become available later upon DxgkDdiPatch.
How to page in the source allocation?2.b. There is one more thing which I already considered saying at the beginning: I do not remember having ever seen any working WDDM driver defining only one video memory segment as yours does. I am not sure if WDDM allows this…
I read VirtualBox WDDM driver source code, And I found it had two segments.
I have modified the code to the following:
if(pDxgkQuerySegOut->pSegmentDescriptor==NULL) {
pDxgkQuerySegOut->NbSegment=2; }
pDxgkSegDesc[0].BaseAddress=m_pHWDevice->m_RamPA;
pDxgkSegDesc[0].CpuTranslatedAddress=m_pHWDevice->m_RamPA;
pDxgkSegDesc[0].Size=0x800000;
pDxgkSegDesc[0].NbOfBnks=0;
pDxgkSegDesc[0].pBankRangeTable=0;
pDxgkSegDesc[0].CommitLimit=pDxgkSegDesc[0].Size;
pDxgkSegDesc[0].Flags.Value=0;
pDxgkSegDesc[0].Flags.CpuVisible=1;
pDxgkSegDesc[1].BaseAddress.QuadPart=0;
pDxgkSegDesc[1].CpuTranslatedAddress.QuadPart=0;
pDxgkSegDesc[1].Size=0x800000;
pDxgkSegDesc[1].NbOfBnks=0;
pDxgkSegDesc[1].pBankRangeTable=0;
pDxgkSegDesc[1].CommitLimit=pDxgkSegDesc[0].Size;
pDxgkSegDesc[1].Flags.Value=0;
pDxgkSegDesc[1].Flags.CpuVisible=0;
One for source allocation, the other for destination allocation, right?
3.a. WDDM assumes DMA (Direct Memory Access) and NOT copying. Copying the data instead of using DMA probably violates WDDM. Having said this, copying can still be done. Theoretically the appropriate place for copying is DxgkDdiSubmitCommand. The problem: Copying screen content at IRQL_DISPATCH_LEVEL can make the whole system unresponsive. Thus copying can only be done in DxgkDdiPresent or DxgkDdiPatch (in case the allocation is not available at DxgkDdiPresent time - see 2.a. above).
3.b. The source bitmap data is NOT located in system memory. It is in an allocation within one of the previously defined video memory segments.
The source bitmap data is located in the member “pPatch-> pAllocationList[DXGK_PRESENT_SOURCE_INDEX].PhysicalAddress” of struct DXGKARG_PATCH in function DxgkDdiPatch, is it?
But after calling DxgkDdiPresent, it doesn’t call DxgkDdiPatch or DxgkDdiSubmitCommand. Instead, it calls as follows:
DxgkDdiSetPointerPosition
DxgkDdiSetVidPnSourceVisibility
case: pSetVidPnSourceVisibility->Visible is false
DxgkDdiBuildPagingBuffer
case: DXGK_OPERATION_DISCARD_CONTENT
DxgkDdiCloseAllocation
DxgkDdiDestroyAllocation
DxgkDdiDestroyContext
DxgkDdiDestroyDevice
what is wrong with it?
Thank you again. Good luck!
Zhengwei lou