PDD_CREATESURFACEEX funzione di callback (ddrawint.h)
La funzione D3dCreateSurfaceEx notifica l'associazione di un'area Microsoft DirectDraw e un valore di handle Microsoft Direct3D per abilitare la configurazione della superficie per il rendering Direct3D.
Sintassi
PDD_CREATESURFACEEX PddCreatesurfaceex;
DWORD PddCreatesurfaceex(
PDD_CREATESURFACEEXDATA unnamedParam1
)
{...}
Parametri
unnamedParam1
Punta a una struttura DD_CREATESURFACEEXDATA che contiene le informazioni necessarie per il driver per creare la superficie.
Valore restituito
D3dCreateSurfaceEx restituisce uno dei codici di callback seguenti:
Commenti
Tutti i driver Direct3D devono supportare D3dCreateSurfaceEx.
D3dCreateSurfaceEx crea un'associazione tra una superficie DirectDraw e un piccolo handle di superficie intero. Creando queste associazioni tra un handle e una superficie DirectDraw, D3dCreateSurfaceEx consente di incorporare un handle di superficie nel flusso di comandi Direct3D. Ad esempio, quando il token di comando D3DDP2OP_TEXBLT viene inviato alla funzione D3dDrawPrimitives2 del driver per caricare una mappa di trama, usa un handle di origine e un handle di destinazione associati a una superficie DirectDraw tramite D3dCreateSurfaceEx.
Per ogni superficie DirectDraw creata nell'oggetto DirectDraw locale, il runtime genera un handle valido che identifica in modo univoco la superficie e inserisce l'handle nel membro dwSurfaceHandle di una struttura DD_SURFACE_MORE . Il membro lpDDSLcl della struttura DD_CREATESURFACEEXDATA in pcsxd punta a una struttura DD_SURFACE_LOCAL che contiene un membro lpSurfMore che punta a questa DD_SURFACE_MORE. Questo valore di handle viene usato anche con lo stato di rendering D3DRENDERSTATE_TEXTUREHANDLE per abilitare il texturing e con i comandi D3DDP2OP_SETRENDERTARGET e D3DDP2OP_CLEAR per impostare e cancellare nuovi buffer di rendering e profondità . Il driver deve non riuscire la chiamata e restituire DDHAL_DRIVER_HANDLED se non riesce a creare la superficie Direct3D.
Per una superficie di memoria di sistema o una superficie di memoria video, quando D3dCreateSurfaceEx viene chiamato a notificare l'associazione di dwSurfaceHandle con le strutture DD_SURFACE_GLOBAL eDD_SURFACE_LOCAL della superficie, il driver di visualizzazione può archiviare tutti i dati (ad esempio un puntatore alla memoria allocata privatamente) nei membri di DD_SURFACE_GLOBAL e DD_SURFACE_LOCAL perché questi membri sono riservati per l'uso privato dal driver di visualizzazione.
Per notificare al driver di visualizzazione che deve essere rilasciata una superficie di memoria di sistema, il runtime imposta il membro del puntatore fpVidMem della struttura DD_SURFACE_GLOBAL della superficie di memoria di sistema su zero e chiama il callback D3dCreateSurfaceEx del driver visualizzato. Oltre a rilasciare tutte le risorse associate a questa superficie, il driver di visualizzazione deve cancellare i dati archiviati in precedenza nei membri dwReserved1 . Si noti che poiché il membro del puntatore fpVidMem per una superficie di memoria video può essere impostato su zero, il driver di visualizzazione deve verificare se la superficie è in memoria video o di sistema per determinare se la chiamata a D3dCreateSurfaceEx è destinata a notificare l'associazione di una superficie di memoria video con dwSurfaceHandle o per notificare la disassociazione di una superficie di memoria di sistema da dwSurfaceHandle.
D3dCreateSurfaceEx non viene chiamato per notificare la disassociazione di una superficie di memoria video da dwSurfaceHandle; il callback DdDestroySurface del driver di visualizzazione deve gestire l'eliminazione della superficie di superficie di memoria video locale e non locale e deve cancellare i dati archiviati in precedenza nei membri dwReserved1 .
Il driver deve anche archiviare tutte le informazioni correlate alla superficie necessarie quando si usa la superficie. Il driver deve creare una nuova tabella di superficie per ogni nuovo lpDDLcl e ingrandire in modo implicito la tabella quando necessario per ospitare più superfici. In genere, questa operazione viene eseguita con un algoritmo di crescita esponenziale in modo che non sia necessario ingrandire troppo spesso la tabella. Per informazioni dettagliate sull'implementazione, vedere il driver di esempio Perm3 incluso in Microsoft Windows Driver Development Kit (DDK). (DDK ha preceduto Windows Driver Kit [WDK].)
D3dCreateSurfaceEx può essere chiamato solo con un PDEV disabilitato per una superficie di memoria di sistema. Un PDEV è disabilitato o abilitato chiamando la funzione DrvAssertMode del driver visualizzato. Per altre informazioni, vedere Gestione di PDEV .
Implementazione di esempio di 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);
}
}
Requisiti
Piattaforma di destinazione | Desktop |
Intestazione | ddrawint.h (include Winddi.h) |