Compartir a través de


PDD_CREATESURFACEEX función de devolución de llamada (ddrawint.h)

La función D3dCreateSurfaceEx notifica a la asociación de una superficie de Microsoft DirectDraw y un valor de identificador de Microsoft Direct3D para habilitar la configuración de la superficie para la representación de Direct3D.

Sintaxis

PDD_CREATESURFACEEX PddCreatesurfaceex;

DWORD PddCreatesurfaceex(
  PDD_CREATESURFACEEXDATA unnamedParam1
)
{...}

Parámetros

unnamedParam1

Apunta a una estructura de DD_CREATESURFACEEXDATA que contiene la información necesaria para que el controlador cree la superficie.

Valor devuelto

D3dCreateSurfaceEx devuelve uno de los siguientes códigos de devolución de llamada:

Comentarios

Todos los controladores de Direct3D deben admitir D3dCreateSurfaceEx.

D3dCreateSurfaceEx crea una asociación entre una superficie de DirectDraw y un pequeño identificador de superficie de entero. Al crear estas asociaciones entre un identificador y una superficie de DirectDraw, D3dCreateSurfaceEx permite incrustar un identificador de superficie en el flujo de comandos de Direct3D. Por ejemplo, cuando el token de comando D3DDP2OP_TEXBLT se envía a la función D3dDrawPrimitives2 del controlador para cargar un mapa de texturas, usa un identificador de origen y un identificador de destino asociados a una superficie de DirectDraw a través de D3dCreateSurfaceEx.

Para cada superficie de DirectDraw creada en el objeto DirectDraw local, el tiempo de ejecución genera un identificador válido que identifica de forma única la superficie y coloca el identificador en el miembro dwSurfaceHandle de una estructura de DD_SURFACE_MORE . El miembro lpDDSLcl de la estructura de DD_CREATESURFACEEXDATA en pcsxd apunta a una estructura DD_SURFACE_LOCAL que contiene un miembro lpSurfMore que apunta a este DD_SURFACE_MORE. Este valor de identificador también se usa con el estado de representación D3DRENDERSTATE_TEXTUREHANDLE para habilitar la texturización y con los comandos D3DDP2OP_SETRENDERTARGET y D3DDP2OP_CLEAR para establecer y borrar nuevos búferes de representación y profundidad. El controlador debe producir un error en la llamada y devolver DDHAL_DRIVER_HANDLED si no puede crear la superficie de Direct3D.

Para una superficie de memoria del sistema o una superficie de memoria de vídeo, cuando se llama a D3dCreateSurfaceEx para notificar la asociación de dwSurfaceHandle con las estructuras de DD_SURFACE_GLOBAL y DD_SURFACE_LOCAL de la superficie, el controlador de pantalla puede almacenar cualquier dato (por ejemplo, un puntero a memoria asignada de forma privada) en los miembros dwReserved1 de DD_SURFACE_GLOBAL y DD_SURFACE_LOCAL porque estos miembros están reservados para uso privado por parte del controlador de pantalla.

Para notificar al controlador de pantalla que se va a liberar una superficie de memoria del sistema, el tiempo de ejecución establece el miembro de puntero fpVidMem de la estructura DD_SURFACE_GLOBAL de la superficie de memoria del sistema en cero y llama a la devolución de llamada D3dCreateSurfaceEx del controlador de pantalla. Además de liberar todos los recursos asociados a esta superficie, el controlador de pantalla debe borrar los datos almacenados anteriormente en los miembros dwReserved1 . Tenga en cuenta que, dado que el miembro de puntero fpVidMem para una superficie de memoria de vídeo se puede establecer en cero, el controlador de pantalla debe comprobar si la superficie está en vídeo o memoria del sistema para determinar si la llamada a D3dCreateSurfaceEx está pensada para notificar sobre la asociación de una superficie de memoria de vídeo con dwSurfaceHandle o para notificar la desasociación de una superficie de memoria del sistema de dwSurfaceHandle.

No se llama a D3dCreateSurfaceEx para notificar sobre la desasociación de una superficie de memoria de vídeo de dwSurfaceHandle; La devolución de llamada DdDestroySurface del controlador de pantalla debe controlar la eliminación de la superficie de memoria de vídeo local y no local y debe borrar los datos almacenados anteriormente en los miembros dwReserved1.

El controlador también debe almacenar cualquier información relacionada con la superficie que necesite al usar la superficie. El controlador debe crear una nueva tabla expuesta para cada nueva lpDDLcl y ampliar implícitamente la tabla cuando sea necesario para acomodar más superficies. Normalmente, esto se hace con un algoritmo de crecimiento exponencial para que no tenga que ampliar la tabla con demasiada frecuencia. Consulta el controlador de ejemplo de Perm3 que se incluyó con el Kit de desarrollo de controladores de Microsoft Windows (DDK) para obtener detalles de implementación. (El DDK precedió al Kit de controladores de Windows [WDK].)

Nota El Kit de controladores de Microsoft Windows (WDK) no contiene el controlador de visualización de ejemplo 3Dlabs Permedia3 (Perm3.htm). Puede obtener este controlador de ejemplo desde el DDK de Windows Server 2003 SP1, que puede descargar desde la página DDK - Kit de desarrollo de controladores de Windows del sitio web de WDHC.
 
Direct3D llama a D3dCreateSurfaceEx después de que DirectDraw cree la superficie mediante la solicitud del tiempo de ejecución de Direct3D o la aplicación.

Solo se puede llamar a D3dCreateSurfaceEx con un PDEV deshabilitado para una superficie de memoria del sistema. Un PDEV está deshabilitado o habilitado llamando a la función DrvAssertMode del controlador de pantalla. Consulte Administración de PDEV para obtener más información.

Implementación de ejemplo 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);
    }
}

Requisitos

   
Plataforma de destino Escritorio
Encabezado ddrawint.h (incluya Winddi.h)

Consulte también

D3DDP2OP_CLEAR

D3DDP2OP_SETRENDERTARGET

D3DDP2OP_TEXBLT

D3dDestroyDDDLocal

D3dDrawPrimitives2

DD_CREATESURFACEEXDATA

DD_SURFACE_GLOBAL

DD_SURFACE_LOCAL

DD_SURFACE_MORE

DdDestroySurface