Partager via


PDD_CREATESURFACEEX fonction de rappel (ddrawint.h)

La fonction D3dCreateSurfaceEx informe de l’association d’une surface Microsoft DirectDraw et d’une valeur de handle Microsoft Direct3D pour activer la configuration de la surface pour le rendu Direct3D.

Syntaxe

PDD_CREATESURFACEEX PddCreatesurfaceex;

DWORD PddCreatesurfaceex(
  PDD_CREATESURFACEEXDATA unnamedParam1
)
{...}

Paramètres

unnamedParam1

Pointe vers une structure DD_CREATESURFACEEXDATA qui contient les informations requises pour que le pilote crée la surface.

Valeur retournée

D3dCreateSurfaceEx retourne l’un des codes de rappel suivants :

Notes

Tous les pilotes Direct3D doivent prendre en charge D3dCreateSurfaceEx.

D3dCreateSurfaceEx crée une association entre une surface DirectDraw et une petite poignée de surface entière. En créant ces associations entre un handle et une surface DirectDraw, D3dCreateSurfaceEx permet d’intégrer un handle de surface dans le flux de commandes Direct3D. Par exemple, lorsque le jeton de commande D3DDP2OP_TEXBLT est envoyé à la fonction D3dDrawPrimitives2 du pilote pour charger une carte de textures, il utilise un handle source et un handle de destination qui ont été associés à une surface DirectDraw via D3dCreateSurfaceEx.

Pour chaque surface DirectDraw créée sous l’objet DirectDraw local, le runtime génère un handle valide qui identifie de manière unique la surface et place le handle dans le membre dwSurfaceHandle d’une structure DD_SURFACE_MORE . Le membre lpDDSLcl de la structure DD_CREATESURFACEEXDATA au niveau de pcsxd pointe vers une structure DD_SURFACE_LOCAL qui contient un membre lpSurfMore qui pointe vers cette DD_SURFACE_MORE. Cette valeur de handle est également utilisée avec l’état de rendu D3DRENDERSTATE_TEXTUREHANDLE pour activer la texturation, ainsi qu’avec les commandes D3DDP2OP_SETRENDERTARGET et D3DDP2OP_CLEAR pour définir et effacer de nouvelles mémoires tampons de rendu et de profondeur. Le pilote doit échouer l’appel et retourner DDHAL_DRIVER_HANDLED s’il ne peut pas créer la surface Direct3D.

Pour une surface mémoire système ou une surface de mémoire vidéo, lorsque D3dCreateSurfaceEx est appelé pour signaler l’association de dwSurfaceHandle avec les structures DD_SURFACE_GLOBAL et DD_SURFACE_LOCAL de la surface, le pilote d’affichage peut stocker toutes les données (par exemple, un pointeur vers la mémoire allouée en privé) dans les membres dwReserved1 de DD_SURFACE_GLOBAL et DD_SURFACE_LOCAL, car ces membres sont réservés à une utilisation privée par le pilote d’affichage.

Pour avertir le pilote d’affichage qu’une surface de mémoire système doit être libérée, le runtime définit le pointeur fpVidMem membre de la structure DD_SURFACE_GLOBAL de la surface de mémoire système sur zéro et appelle le rappel D3dCreateSurfaceEx du pilote d’affichage. En plus de libérer toutes les ressources associées à cette surface, le pilote d’affichage doit effacer les données précédemment stockées dans les membres dwReserved1 . Notez que étant donné que le membre pointeur fpVidMem d’une surface de mémoire vidéo peut être défini sur zéro, le pilote d’affichage doit vérifier si la surface est en mémoire vidéo ou système pour déterminer si l’appel à D3dCreateSurfaceEx est destiné à notifier l’association d’une surface mémoire vidéo avec dwSurfaceHandle ou à notifier la dissociation d’une surface mémoire système de dwSurfaceHandle.

D3dCreateSurfaceEx n’est pas appelé pour notifier la dissociation d’une surface mémoire vidéo de dwSurfaceHandle ; Le rappel DdDestroySurface du pilote d’affichage doit gérer la suppression de la surface mémoire vidéo locale et non locale et doit effacer les données précédemment stockées dans les membres dwReserved1 .

Le pilote doit également stocker toutes les informations relatives à la surface dont il a besoin lors de l’utilisation de la surface. Le pilote doit créer une nouvelle table de surfaces pour chaque nouveau lpDDLcl et agrandir implicitement la table si nécessaire pour prendre en charge davantage de surfaces. En règle générale, cela se fait avec un algorithme de croissance exponentielle afin que vous n’ayez pas à agrandir la table trop souvent. Pour plus d’informations sur l’implémentation, consultez l’exemple de pilote Perm3 fourni avec le Kit de développement de pilotes Microsoft Windows (DDK). (Le DDK a précédé le Kit de pilotes Windows [WDK].)

Note Le Kit de pilotes Microsoft Windows (WDK) ne contient pas l’exemple de pilote d’affichage 3Dlabs Permedia3 (Perm3.htm). Vous pouvez obtenir cet exemple de pilote à partir du DDK Windows Server 2003 SP1, que vous pouvez télécharger à partir de la page DDK - Kit de développement de pilotes Windows du site web WDHC.
 
Direct3D appelle D3dCreateSurfaceEx une fois la surface créée par DirectDraw à la demande du runtime Direct3D ou de l’application.

D3dCreateSurfaceEx ne peut être appelé qu’avec un PDEV désactivé pour une surface de mémoire système. Un PDEV est désactivé ou activé en appelant la fonction DrvAssertMode du pilote d’affichage. Pour plus d’informations, consultez Gestion des PDEV .

Exemple d’implémentation de 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);
    }
}

Spécifications

   
Plateforme cible Desktop (Expérience utilisateur)
En-tête ddrawint.h (incluez Winddi.h)

Voir aussi

D3DDP2OP_CLEAR

D3DDP2OP_SETRENDERTARGET

D3DDP2OP_TEXBLT

D3dDestroyDDLocal

D3dDrawPrimitives2

DD_CREATESURFACEEXDATA

DD_SURFACE_GLOBAL

DD_SURFACE_LOCAL

DD_SURFACE_MORE

DdDestroySurface