Freigeben über


PDD_CREATESURFACEEX Rückruffunktion (ddrawint.h)

Die D3dCreateSurfaceEx-Funktion informiert über die Zuordnung einer Microsoft DirectDraw-Oberfläche und eines Microsoft Direct3D-Handle-Werts, um das Einrichten der Oberfläche für das Direct3D-Rendering zu aktivieren.

Syntax

PDD_CREATESURFACEEX PddCreatesurfaceex;

DWORD PddCreatesurfaceex(
  PDD_CREATESURFACEEXDATA unnamedParam1
)
{...}

Parameter

unnamedParam1

Zeigt auf eine DD_CREATESURFACEEXDATA-Struktur , die die Informationen enthält, die für den Treiber zum Erstellen der Oberfläche erforderlich sind.

Rückgabewert

D3dCreateSurfaceEx gibt einen der folgenden Rückrufcodes zurück:

Hinweise

Alle Direct3D-Treiber müssen D3dCreateSurfaceEx unterstützen.

D3dCreateSurfaceEx erstellt eine Zuordnung zwischen einer DirectDraw-Oberfläche und einem kleinen ganzzahligen Flächenhandle. Durch das Erstellen dieser Zuordnungen zwischen einem Handle und einer DirectDraw-Oberfläche ermöglicht D3dCreateSurfaceEx , dass ein Oberflächenhandle in den Direct3D-Befehlsstream eingebettet wird. Wenn das D3DDP2OP_TEXBLT-Befehlstoken beispielsweise an die D3dDrawPrimitives2-Funktion des Treibers gesendet wird, um eine Texturzuordnung zu laden, wird ein Quellhandle und ein Zielhandle verwendet, die einer DirectDraw-Oberfläche über D3dCreateSurfaceEx zugeordnet waren.

Für jede DirectDraw-Oberfläche, die unter dem lokalen DirectDraw-Objekt erstellt wird, generiert die Runtime ein gültiges Handle, das die Oberfläche eindeutig identifiziert und das Handle im dwSurfaceHandle-Member einer DD_SURFACE_MORE-Struktur platziert. Das lpDDSLcl-Element der DD_CREATESURFACEEXDATA-Struktur bei pcsxd verweist auf eine DD_SURFACE_LOCAL-Struktur , die einen lpSurfMore-Member enthält, der auf diese DD_SURFACE_MORE verweist. Dieser Handle-Wert wird auch mit dem D3DRENDERSTATE_TEXTUREHANDLE Renderzustand zum Aktivieren der Texturierung und mit den Befehlen D3DDP2OP_SETRENDERTARGET und D3DDP2OP_CLEAR verwendet, um neue Rendering- und Tiefenpuffer festzulegen und zu löschen. Der Treiber sollte den Aufruf nicht ausführen und DDHAL_DRIVER_HANDLED zurückgeben, wenn die Direct3D-Oberfläche nicht erstellt werden kann.

Wenn D3dCreateSurfaceEx aufgerufen wird, um über die Zuordnung von dwSurfaceHandle mit den DD_SURFACE_GLOBAL - und DD_SURFACE_LOCAL Strukturen des Surface zu informieren, kann der Anzeigetreiber alle Daten (z. B. einen Zeiger auf den privat zugeordneten Speicher) in den dwReserved1-Membern von DD_SURFACE_GLOBAL und DD_SURFACE_LOCAL speichern, da diese Member für die private Verwendung durch den Anzeigetreiber reserviert sind.

Um den Anzeigetreiber darüber zu benachrichtigen, dass eine Systemspeicheroberfläche freigegeben werden soll, legt die Runtime den fpVidMem-Zeigermitglied der DD_SURFACE_GLOBAL Struktur der Systemspeicheroberfläche auf Null fest und ruft den D3dCreateSurfaceEx-Rückruf des Anzeigetreibers auf. Zusätzlich zum Freigeben aller Ressourcen, die dieser Oberfläche zugeordnet sind, muss der Anzeigetreiber die Daten löschen, die zuvor in den dwReserved1-Membern gespeichert wurden. Beachten Sie, dass der fpVidMem-Zeigermem für eine Videospeicheroberfläche auf null festgelegt werden kann, der Anzeigetreiber überprüfen muss, ob sich die Oberfläche im Video- oder Systemspeicher befindet, um festzustellen, ob der Aufruf von D3dCreateSurfaceEx dazu bestimmt ist, über die Zuordnung einer Videospeicheroberfläche mit dwSurfaceHandle oder über die Trennung einer Systemspeicheroberfläche von dwSurfaceHandle zu informieren.

D3dCreateSurfaceEx wird nicht aufgerufen, um über die Trennung einer Videospeicheroberfläche von dwSurfaceHandle zu informieren. der DdDestroySurface-Rückruf des Anzeigetreibers muss das lokale und nicht lokale Löschen der Videospeicheroberfläche verarbeiten und Daten löschen, die zuvor in den dwReserved1-Membern gespeichert wurden.

Der Treiber sollte auch alle oberflächenbezogenen Informationen speichern, die er bei der Verwendung des Surface benötigt. Der Treiber muss eine neue Oberflächentabelle für jede neue lpDDLcl erstellen und die Tabelle bei Bedarf implizit vergrößern, um weitere Oberflächen aufzunehmen. In der Regel erfolgt dies mit einem Algorithmus für exponentielles Wachstum, sodass Sie die Tabelle nicht zu oft vergrößern müssen. Implementierungsdetails finden Sie im Perm3-Beispieltreiber , der im Microsoft Windows Driver Development Kit (DDK) enthalten war. (Das DDK war dem Windows Driver Kit [WDK] vorangestellt.)

Hinweis Das Microsoft Windows Driver Kit (WDK) enthält nicht den Beispieltreiber 3Dlabs Permedia3 (Perm3.htm). Sie können diesen Beispieltreiber aus dem Windows Server 2003 SP1 DDK abrufen, den Sie auf der Seite DDK - Windows Driver Development Kit der WDHC-Website herunterladen können.
 
Direct3D ruft D3dCreateSurfaceEx auf, nachdem die Oberfläche von DirectDraw auf Anforderung der Direct3D-Runtime oder der Anwendung erstellt wurde.

D3dCreateSurfaceEx kann nur mit einem deaktivierten PDEV für eine Systemspeicheroberfläche aufgerufen werden. Ein PDEV wird durch Aufrufen der DrvAssertMode-Funktion des Anzeigetreibers deaktiviert oder aktiviert. Weitere Informationen finden Sie unter Verwalten von PDEVs .

Beispielimplementierung von D3dCreateSurfaceEx

LPDDRAWI_DDRAWSURFACE_LCL GetAttachedSurface(
    LPDDRAWI_DDRAWSURFACE_LCL pLcl,
    DDSCAPS2 * pddsCaps2)
{
    LPATTACHLIST pAl;
    pAl = pLcl->lpAttachList;
    while (pAl) {
        LPDDRAWI_DDRAWSURFACE_LCL pLclAttached = pAl->lpAttached;
        LPATTACHLIST pAlAttached = pLclAttached->lpAttachList;
        if ((pLclAttached->lpSurfMore->ddsCapsEx.dwCaps2 & pddsCaps2->dwCaps2) ||
            (pLclAttached->lpSurfMore->ddsCapsEx.dwCaps3 & pddsCaps2->dwCaps3) ||
            (pLclAttached->lpSurfMore->ddsCapsEx.dwCaps4 & pddsCaps2->dwCaps4) ||
            (pLclAttached->ddsCaps.dwCaps & pddsCaps2->dwCaps)
            )
        {
            return pLclAttached;
        }
        pAl = pAl->lpLink;
    }
    return NULL;
}
 
 
void CSExProcessPossibleMipmap(LPDDRAWI_DDRAWSURFACE_LCL pLcl)
{
    //
    // A more likely scenario would be to build a list of surfaces
    // so that the driver can create one structure that represents the
    // entire mipmap, rather than creating an object to represent each
    // level as depicted here.
    //
    DDSCAPS2 ddsCaps2 = {0,DDSCAPS2_MIPMAPSUBLEVEL,0,0};
    while (pLcl) {
        //Call the private driver routine that creates a driver-side surface structure
        CreateMyRepresentation(pLcl);
        pLcl = GetAttachedSurface(pLcl,&ddsCaps2);
    }
}

//
// The actual return type should reflect the fact that the only
// way this routine should fail is with DDERR_OUTOFMEMORY
//
void MyCreateSurfaceExHelper(LPDDRAWI_DDRAWSURFACE_LCL pLcl)
{
    LPATTACHLIST pAl;
    DDSCAPS2 ddsCaps2 = {0,0,0,0};
    LPDDRAWI_DDRAWSURFACE_LCL pLclAttached;
    LPDDRAWI_DDRAWSURFACE_LCL pLclStart;
    if (pLcl->lpGbl->fpVidMem == 0) {
        //A required check against bad surfaces
        if (pLcl->ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)
            return;
        //Else, this is a system memory surface, so we are being informed of
        // its destruction
        DestroyMyRepresentation(pLcl->lpSurfMore->dwSurfaceHandle);
        return;
    }
    CSExProcessPossibleMipmap(pLcl);
    if (pLcl->lpSurfMore->ddsCapsEx.dwCaps2 & DDSCAPS2_CUBEMAP) {
        int i;
        //
        // The root surface is always positive X, so we check for the
        // other five face types.
        // 
        DWORD dw[5] = {
            DDSCAPS2_CUBEMAP_NEGATIVEX,
            DDSCAPS2_CUBEMAP_POSITIVEY,
            DDSCAPS2_CUBEMAP_NEGATIVEY,
            DDSCAPS2_CUBEMAP_POSITIVEZ,
            DDSCAPS2_CUBEMAP_NEGATIVEZ};
        for(i=0;i< sizeof(dw)/sizeof(dw[0]);i++) {
            ddsCaps2.dwCaps2 = dw[i];
            pLclAttached = GetAttachedSurface(pLcl, &ddsCaps2);
            if (pLclAttached)
                CSExProcessPossibleMipmap(pLclAttached);
        }
        //
        // Once we know it's a cube map, we know there cannot be any other 
        // attachments.
        //
        return; 
    }
    //
    // At this point:
    //      If it's a cubemap, we returned above.
    //      If it's a mipmap, we handled all cases above.
    // The only other complex surface possibility is a primary flipping chain.
    // Because a primary flipping chain cannot be mipmapped, we will simply return
    // here if this surface is a mipmap.
    //
    if (pLcl->ddsCaps.dwCaps & DDSCAPS_MIPMAP)
        return;
    //
    // The only system memory surfaces we'll ever be interested in are textures (mipmaps)
    // and cube maps.   We do not propagate an error code for system memory
    // surfaces whose format we do not understand. This could cause an error code to 
    // be propagated to the application when it was trying to use system memory surfaces
    // of a format we do not understand, but is valid for the reference rasterizer, for example.
    //
    if (pLcl->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY)
        return;
    //
    // Now walk around a flipping chain. A flipping chain is a ring of
    // surfaces attached to each other (each surface is attached to the next
    // and to the previous surface in the ring, but not to any other surface
    // in the ring).
    // We need to watch out for this circular ring and make sure we exit appropriately.
    // There is also the possibility of a z buffer attached to one of the surfaces
    // in the ring, which may or may not have been CreateSurfaceEx'ed already.
    //
    pLclStart = pLcl;
    while (pLcl && pLcl != pLclStart) {
        //Check for Z buffer attached to this surface in the ring.
        ddsCaps2.dwCaps = DDSCAPS_ZBUFFER;
        ddsCaps2.dwCaps2 = 0;
        pLclAttached = GetAttachedSurface(pLcl, &ddsCaps2);
        if (pLclAttached)
            CreateMyRepresentation(pLclAttached);
        //Check for stereo left surface attached to this surface in the ring
        ddsCaps2.dwCaps = 0;
        ddsCaps2.dwCaps2 = DDSCAPS2_STEREOSURFACELEFT;
        pLclAttached = GetAttachedSurface(pLcl, &ddsCaps2);
        if (pLclAttached)
            CreateMyRepresentation(pLclAttached);
        // Move to next surface in the primary flipping ring. The next surface is 
        // definitely in video memory (all surfaces in an attachment structure have
        // to be in the same memory type, and we excluded system memory above).
        // The next surface in the ring is thus the attached video memory surface
        // that is NOT a z buffer NOR a stereo left surface.
        ddsCaps2.dwCaps = DDSCAPS_VIDEOMEMORY;
        ddsCaps2.dwCaps2 = 0;
        do {
            pLclAttached = GetAttachedSurface(pLcl, &ddsCaps2);
        }
        while (
            pLclAttached->ddsCaps.dwCaps & DDSCAPS_ZBUFFER ||
            pLclAttached->lpSurfMore->ddsCapsEx.dwCaps2 & DDSCAPS2_STEREOSURFACELEFT
            );
        pLcl = pLclAttached;
        if (pLcl != pLclStart)
            CreateMyRepresentation(pLcl);
    }
}

Anforderungen

   
Zielplattform Desktop
Kopfzeile ddrawint.h (include Winddi.h)

Weitere Informationen

D3DDP2OP_CLEAR

D3DDP2OP_SETRENDERTARGET

D3DDP2OP_TEXBLT

D3dDestroyDLocal

D3dDrawPrimitives2

DD_CREATESURFACEEXDATA

DD_SURFACE_GLOBAL

DD_SURFACE_LOCAL

DD_SURFACE_MORE

DdDestroySurface