Compartilhar via


PDD_CREATESURFACEEX função de retorno de chamada (ddrawint.h)

A função D3dCreateSurfaceEx notifica sobre a associação de uma superfície do Microsoft DirectDraw e um valor de identificador do Microsoft Direct3D para habilitar a configuração da superfície para renderização do Direct3D.

Sintaxe

PDD_CREATESURFACEEX PddCreatesurfaceex;

DWORD PddCreatesurfaceex(
  PDD_CREATESURFACEEXDATA unnamedParam1
)
{...}

Parâmetros

unnamedParam1

Aponta para uma estrutura DD_CREATESURFACEEXDATA que contém as informações necessárias para o driver criar a superfície.

Valor retornado

D3dCreateSurfaceEx retorna um dos seguintes códigos de retorno de chamada:

Comentários

Todos os drivers Direct3D devem dar suporte a D3dCreateSurfaceEx.

D3dCreateSurfaceEx cria uma associação entre uma superfície DirectDraw e um identificador de superfície de inteiro pequeno. Ao criar essas associações entre um identificador e uma superfície DirectDraw, D3dCreateSurfaceEx permite que um identificador de superfície seja inserido no fluxo de comandos direct3D. Por exemplo, quando o token de comando D3DDP2OP_TEXBLT é enviado para a função D3dDrawPrimitives2 do driver para carregar um mapa de textura, ele usa um identificador de origem e um identificador de destino associados a uma superfície DirectDraw por meio de D3dCreateSurfaceEx.

Para cada superfície DirectDraw criada sob o objeto DirectDraw local, o runtime gera um identificador válido que identifica exclusivamente a superfície e coloca o identificador no membro dwSurfaceHandle de uma estrutura DD_SURFACE_MORE . O membro lpDDSLcl da estrutura DD_CREATESURFACEEXDATA em pcsxd aponta para uma estrutura DD_SURFACE_LOCAL que contém um membro lpSurfMore que aponta para esse DD_SURFACE_MORE. Esse valor de identificador também é usado com o estado de renderização D3DRENDERSTATE_TEXTUREHANDLE para habilitar a texturização e com os comandos D3DDP2OP_SETRENDERTARGET e D3DDP2OP_CLEAR para definir e limpar novos buffers de renderização e profundidade. O driver deverá falhar na chamada e retornar DDHAL_DRIVER_HANDLED se não puder criar a superfície Direct3D.

Para uma superfície de memória do sistema ou uma superfície de memória de vídeo, quando D3dCreateSurfaceEx é chamado para notificar sobre a associação de dwSurfaceHandle com as estruturas DD_SURFACE_GLOBAL e DD_SURFACE_LOCAL da superfície, o driver de exibição pode armazenar quaisquer dados (por exemplo, um ponteiro para memória alocada privada) nos membros dwReserved1 de DD_SURFACE_GLOBAL e DD_SURFACE_LOCAL porque esses membros são reservados para uso privado pelo driver de exibição.

Para notificar o driver de exibição de que uma superfície de memória do sistema deve ser liberada, o runtime define o membro do ponteiro fpVidMem da estrutura DD_SURFACE_GLOBAL da superfície de memória do sistema como zero e chama o retorno de chamada D3dCreateSurfaceEx do driver de exibição. Além de liberar todos os recursos associados a essa superfície, o driver de exibição deve limpar os dados armazenados anteriormente nos membros dwReserved1 . Observe que, como o membro do ponteiro fpVidMem para uma superfície de memória de vídeo pode ser definido como zero, o driver de exibição deve verificar se a superfície está em vídeo ou na memória do sistema para determinar se a chamada para D3dCreateSurfaceEx destina-se a notificar sobre a associação de uma superfície de memória de vídeo com dwSurfaceHandle ou notificar sobre a desassociação de uma superfície de memória do sistema de dwSurfaceHandle.

D3dCreateSurfaceEx não é chamado para notificar sobre a desassociação de uma superfície de memória de vídeo de dwSurfaceHandle; O retorno de chamada DdDestroySurface do driver de exibição deve lidar com a exclusão de superfície de memória de vídeo local e não local e deve limpar os dados que foram armazenados anteriormente nos membros dwReserved1 .

O driver também deve armazenar todas as informações relacionadas à superfície necessárias ao usar a superfície. O driver deve criar uma nova tabela de superfície para cada novo lpDDLcl e ampliar implicitamente a tabela quando necessário para acomodar mais superfícies. Normalmente, isso é feito com um algoritmo de crescimento exponencial para que você não precise ampliar a tabela com muita frequência. Consulte o driver de exemplo Perm3 que foi incluído no DDK (Microsoft Windows Driver Development Kit) para obter detalhes da implementação. (O DDK precedeu o Kit de Driver do Windows [WDK].)

Nota O WDK (Microsoft Windows Driver Kit) não contém o driver de exibição de exemplo 3Dlabs Permedia3 (Perm3.htm). Você pode obter esse driver de exemplo do DDK do Windows Server 2003 SP1, que pode ser baixado na página DDK – Windows Driver Development Kit do site do WDHC.
 
O Direct3D chama D3dCreateSurfaceEx depois que a superfície é criada pelo DirectDraw por solicitação do runtime do Direct3D ou do aplicativo.

D3dCreateSurfaceEx só pode ser chamado com um PDEV desabilitado para uma superfície de memória do sistema. Um PDEV está desabilitado ou habilitado chamando a função DrvAssertMode do driver de exibição. Consulte Gerenciando PDEVs para obter mais informações.

Implementação de exemplo 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 Área de Trabalho
Cabeçalho ddrawint.h (inclua Winddi.h)

Confira também

D3DDP2OP_CLEAR

D3DDP2OP_SETRENDERTARGET

D3DDP2OP_TEXBLT

D3dDestroyDDLocal

D3dDrawPrimitives2

DD_CREATESURFACEEXDATA

DD_SURFACE_GLOBAL

DD_SURFACE_LOCAL

DD_SURFACE_MORE

DdDestroySurface