Nvidia Graphics called MmGetPhysicalAddress Error in Vista?

Hi All,

I’m developing a PCI video card driver based on WDK6000.
In App, I Created a DirectDraw object[m_lpDD2] and a DirectDrawSurface object[m_pOverlayOffback].
Then I get the physical address of the surface memory[called function MmGetPhysicalAddress],
It[the physical address] is a parameter to do video preview.

Error happens:
When Our Graphics is Nvidia Series and OS is Vista,blue screen happend when I do video preview.
But when OS is XP or Our Graphics is ATI Series,no error happened,
I can do video preview and our video card works properly.
I updated the latest Nvidia Graphics driver in Vista,error happened also.

Then I traced the “physicalAddr” in XP and Vista used the same Nvidia Graphics to do video preview.
Found that In XP “physicalAddr” is somthing like “0xc030e000”,in Vista it is somthing like “0x13f9f000”.
I opend “Device Manager->Display adapters->Nvidia Grahics”,choose “Properties->Resources”,
it shows “Memory Range C0000000-CFFFFFFF”.
So I guessed:In XP,“0xc030e000”[physicalAddr] is between “C0000000” and “CFFFFFFF”.
In Vista,“0x13f9f000” is not in the range,“physicalAddr” is illegal so blue screen happend.

Is my guess reasonable?
How can I do to help to solve this problem?
Any help is appreciated.Thanks.

Best Regards
Zhou ChengJun

Related to the code below[Simplify]:

LPDIRECTDRAW7 m_lpDD2 ;
DDSURFACEDESC2 ddsd;
LPDIRECTDRAWSURFACE7 m_pOverlayOffback;
ULONG m_nVirtualAddress;
UINT physicalAddr;

App:


DirectDrawCreateEx(NULL, (void **)&m_lpDD2, IID_IDirectDraw7,NULL);

memset((&ddsd),sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);

m_lpDD2->CreateSurface(&ddsd, &m_pOverlayOffback,NULL)
m_pOverlayOffback->Lock(NULL,&ddsd,DDLOCK_WAIT,NULL)
m_nVirtualAddress = (ULONG)ddsd.lpSurface;

MapVirtualAddrToPhysicalAddr(m_nVirtualAddress,physicalAddr);
//defined DeviceIoControl

Driver[IOCTL]:

physicalAddr = MmGetPhysicalAddress((void *)m_nVirtualAddress).LowPart;

I thought a feature of Vista and WDDM was that apps never directly access
actual frame buffers. They access a memory based frame buffer (a texture
buffer) that is then composited into the correct z-order by the display
hardware. I’d assume buffers in normal memory (or pool) will NOT be
physically contigious, so MmGetPhysicalAddress only returns the address of
the first page. Actually, MmGetPhysicalAddress also doesn’t apply bus
relative physical address mapping, so it’s not really useful to always get
the actual physical address. You need a DMA adapter object to do the address
mapping calculation. Is the ATI driver possibly an old XP dirver and the
NVidia driver a new WDDM driver?

It seems like you should be taking the application virtual address and
building an MDL which is then locked. You then have to use a DMA adapter
object to map the MDL to a scatter gather list. Is it possible your video
capture hardware can’t write to a scattered buffer?

Can one of you WDDM developers tell us if a DD surface has to be physically
contigious? I’d assume not, but I’m not really a display driver specialist.
They MIGHT happen to be contigious on some revisions of some drivers for
some hardware.

A blue screen might be the effect of DMAing the captured frame into what you
thought was a contigious buffer, when it’s not.

Jan

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@yahoo.com.cn
Sent: Monday, March 03, 2008 12:35 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] Nvidia Graphics called MmGetPhysicalAddress
Error in Vista?

Hi All,

I’m developing a PCI video card driver based on WDK6000.
In App, I Created a DirectDraw object[m_lpDD2] and a
DirectDrawSurface object[m_pOverlayOffback].
Then I get the physical address of the surface memory[called
function MmGetPhysicalAddress], It[the physical address] is a
parameter to do video preview.

Error happens:
When Our Graphics is Nvidia Series and OS is Vista,blue
screen happend when I do video preview.
But when OS is XP or Our Graphics is ATI Series,no error
happened, I can do video preview and our video card works properly.
I updated the latest Nvidia Graphics driver in Vista,error
happened also.

Then I traced the “physicalAddr” in XP and Vista used the
same Nvidia Graphics to do video preview.
Found that In XP “physicalAddr” is somthing like
“0xc030e000”,in Vista it is somthing like “0x13f9f000”.
I opend “Device Manager->Display adapters->Nvidia
Grahics”,choose “Properties->Resources”, it shows “Memory
Range C0000000-CFFFFFFF”.
So I guessed:In XP,“0xc030e000”[physicalAddr] is between
“C0000000” and “CFFFFFFF”.
In Vista,“0x13f9f000” is not in the range,“physicalAddr” is
illegal so blue screen happend.

Is my guess reasonable?
How can I do to help to solve this problem?
Any help is appreciated.Thanks.

Best Regards
Zhou ChengJun

Related to the code below[Simplify]:

LPDIRECTDRAW7 m_lpDD2 ;
DDSURFACEDESC2 ddsd;
LPDIRECTDRAWSURFACE7 m_pOverlayOffback;
ULONG m_nVirtualAddress;
UINT physicalAddr;

App:


DirectDrawCreateEx(NULL, (void **)&m_lpDD2, IID_IDirectDraw7,NULL);

memset((&ddsd),sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);

m_lpDD2->CreateSurface(&ddsd, &m_pOverlayOffback,NULL)
m_pOverlayOffback->Lock(NULL,&ddsd,DDLOCK_WAIT,NULL)
m_nVirtualAddress = (ULONG)ddsd.lpSurface;

MapVirtualAddrToPhysicalAddr(m_nVirtualAddress,physicalAddr);
//defined DeviceIoControl

Driver[IOCTL]:

physicalAddr = MmGetPhysicalAddress((void
*)m_nVirtualAddress).LowPart;


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online
at http://www.osronline.com/page.cfm?name=ListServer

Why do you need a physical address?


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

wrote in message news:xxxxx@ntdev…
> Hi All,
>
> I’m developing a PCI video card driver based on WDK6000.
> In App, I Created a DirectDraw object[m_lpDD2] and a DirectDrawSurface
object[m_pOverlayOffback].
> Then I get the physical address of the surface memory[called function
MmGetPhysicalAddress],
> It[the physical address] is a parameter to do video preview.
>
> Error happens:
> When Our Graphics is Nvidia Series and OS is Vista,blue screen happend when I
do video preview.
> But when OS is XP or Our Graphics is ATI Series,no error happened,
> I can do video preview and our video card works properly.
> I updated the latest Nvidia Graphics driver in Vista,error happened also.
>
> Then I traced the “physicalAddr” in XP and Vista used the same Nvidia
Graphics to do video preview.
> Found that In XP “physicalAddr” is somthing like “0xc030e000”,in Vista it is
somthing like “0x13f9f000”.
> I opend “Device Manager->Display adapters->Nvidia Grahics”,choose
“Properties->Resources”,
> it shows “Memory Range C0000000-CFFFFFFF”.
> So I guessed:In XP,“0xc030e000”[physicalAddr] is between “C0000000” and
“CFFFFFFF”.
> In Vista,“0x13f9f000” is not in the range,“physicalAddr” is illegal so blue
screen happend.
>
> Is my guess reasonable?
> How can I do to help to solve this problem?
> Any help is appreciated.Thanks.
>
>
>
> Best Regards
> Zhou ChengJun
>
> Related to the code below[Simplify]:
>
>
> LPDIRECTDRAW7 m_lpDD2 ;
> DDSURFACEDESC2 ddsd;
> LPDIRECTDRAWSURFACE7 m_pOverlayOffback;
> ULONG m_nVirtualAddress;
> UINT physicalAddr;
>
> App:
>
> …
> DirectDrawCreateEx(NULL, (void **)&m_lpDD2, IID_IDirectDraw7,NULL);
> …
> memset((&ddsd),sizeof(ddsd));
> ddsd.dwSize = sizeof(ddsd);
> …
> m_lpDD2->CreateSurface(&ddsd, &m_pOverlayOffback,NULL)
> m_pOverlayOffback->Lock(NULL,&ddsd,DDLOCK_WAIT,NULL)
> m_nVirtualAddress = (ULONG)ddsd.lpSurface;
> …
> MapVirtualAddrToPhysicalAddr(m_nVirtualAddress,physicalAddr);
> //defined DeviceIoControl
>
>
>
> Driver[IOCTL]:
>
> physicalAddr = MmGetPhysicalAddress((void *)m_nVirtualAddress).LowPart;
> …
>
>

> So I guessed:In XP,“0xc030e000”[physicalAddr] is between “C0000000” and “CFFFFFFF”. In Vista,“0x13f9f000” is not in the range,“physicalAddr” is illegal so blue screen happend.

It seems in XP you got a video memory and in Vista it’s a regular paged system memory. You may try to retrieve Phys.Address for each page of the buffer and find out if it’s contiguous.
I had the same problem with nVidia using textures. Physically the textures allocated in GPU memory but by Lock() the texture copied into system memory and copied back by Unlock() call. It may be the same with surfaces.

Maxim S. Shatskih wrote:

Why do you need a physical address?

He’s probably doing some kind of video port, where he has a capture card
that wants to DMA directly into the frame buffer.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Jan Bottorff wrote:

Can one of you WDDM developers tell us if a DD surface has to be physically
contigious? I’d assume not, but I’m not really a display driver specialist.
They MIGHT happen to be contigious on some revisions of some drivers for
some hardware.

A system memory surface does not have to be contiguous. A device memory
surface will be.

The OP can look at the capability bits in the surface description to see
if DDSCAPS_SYSTEMMEMORY is set. In that case, he should probably skip
trying to do a direct preview.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Thank you all for your answer.

Well,I tried Intel(R) 82945G Express Graphics today,it worked as Nvidia Series
–I can do video preview and our video card works properly in XP but blue screen happend in Vista.

To Tim Roberts:
The capability bits in the surface description is:
ddsd.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN| DDSCAPS_VIDEOMEMORY;
ddsd.ddpfPixelFormat={sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16, 0x7C00, 0x03e0, 0x001F, 0};
// pixel format – 16-bit RGB 5:5:5

I changed “DDSCAPS_VIDEOMEMORY” to “DDSCAPS_SYSTEMMEMORY”,
but called "m_lpDD2->CreateSurface(&ddsd, &m_pOverlayOffback,NULL)"failed.
[DDERR_INVALIDPIXELFORMAT–“The pixel format was invalid as specified”]

To Igor Kravchenko:
How you solve the problem using textures with nVidia?
Can you say more detaily?

Best Regards
Zhou ChengJun

> How you solve the problem using textures with nVidia? Can you say more detaily?

It’s not solved yet. Our product worked well with nVidia FX-3500 but sometimes I had SCATTER_GATHER_LIST::NumberOfElements > 1.
Our card does not support scatter-gather and I just rejected request to start DMA.
When we tryed to switch to nVidia FX-3700 we’ve had NumberOfElements > 1 every time.
I found the PhysAddr was not in the video adapter range (c0000000-cfffffff).
After some testing I found the same problem on FX-3500 in case if the texture height is power of 2 (128, 256, …).
We have contacted with nVidia and (it took more than month) they confirmed they are using the buffering in the system memory for the textures. In old driver it was done for power of 2 textures only.
For now they promised to give us the special API for video memory access.

Try contact nVidia.
You may check the surface’s height. If it’s power of 2 - try change the size. It may help as workaround but may not work with a next nVidia driver version.

xxxxx@yahoo.com.cn wrote:

Thank you all for your answer.

Well,I tried Intel(R) 82945G Express Graphics today,it worked as Nvidia Series
–I can do video preview and our video card works properly in XP but blue screen happend in Vista.

To Tim Roberts:
The capability bits in the surface description is:
ddsd.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN| DDSCAPS_VIDEOMEMORY;
ddsd.ddpfPixelFormat={sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16, 0x7C00, 0x03e0, 0x001F, 0};
// pixel format – 16-bit RGB 5:5:5

Those are the capabilities you ASKED for. They are not necessarily the
capabilities of the surface you were assigned.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Ok, I will continue to test and debug.Thanks.