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].)
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) |