共用方式為


PDD_CREATESURFACEEX回呼函式 (ddrawint.h)

D3dCreateSurfaceEx函式會通知 Microsoft DirectDraw 表面與 Microsoft Direct3D 控制碼值的關聯,以啟用設定 Direct3D 轉譯的介面。

語法

PDD_CREATESURFACEEX PddCreatesurfaceex;

DWORD PddCreatesurfaceex(
  PDD_CREATESURFACEEXDATA unnamedParam1
)
{...}

參數

unnamedParam1

指向 DD_CREATESURFACEEXDATA 結構,其中包含驅動程式建立介面所需的資訊。

傳回值

D3dCreateSurfaceEx 會傳回下列其中一個回呼代碼:

備註

所有 Direct3D 驅動程式都必須支援 D3dCreateSurfaceEx

D3dCreateSurfaceEx 會建立 DirectDraw 表面與小型整數表面控點之間的關聯。 藉由在控制碼與 DirectDraw 表面之間建立這些關聯, D3dCreateSurfaceEx 可讓 Surface 控制碼內嵌在 Direct3D 命令資料流程中。 例如,當 D3DDP2OP_TEXBLT 命令權杖傳送至驅動程式的 D3dDrawPrimitives2 函式以載入紋理貼圖時,它會使用透過 D3dCreateSurfaceEx與 DirectDraw 表面相關聯的來源控制碼和目的地控制碼。

針對在本機 DirectDraw 物件下建立的每個 DirectDraw 表面,執行時間會產生可唯一識別表面的有效控制碼,並將控制碼放在DD_SURFACE_MORE結構的dwSurfaceHandle成員中。 pcsxd DD_CREATESURFACEEXDATA 結構的lpDDSLcl成員指向指向這個DD_SURFACE_MORE的lpSurfMore成員的DD_SURFACE_LOCAL結構。 此控制碼值也會與D3DRENDERSTATE_TEXTUREHANDLE轉譯狀態搭配使用,以啟用文字處理,以及 D3DDP2OP_SETRENDERTARGETD3DDP2OP_CLEAR 命令來設定和清除新的轉譯和深度緩衝區。 如果驅動程式無法建立 Direct3D 表面,驅動程式應該會失敗呼叫並傳回DDHAL_DRIVER_HANDLED。

針對系統記憶體介面或視訊記憶體表面,當呼叫 D3dCreateSurfaceEx 以通知 dwSurfaceHandle 與表面 DD_SURFACE_GLOBALDD_SURFACE_LOCAL 結構的關聯時,顯示驅動程式可以儲存任何資料 (例如 ,dwReserved1 中私下配置記憶體) 的指標DD_SURFACE_GLOBAL和DD_SURFACE_LOCAL的成員,因為這些成員會保留供顯示驅動程式私用使用。

若要通知顯示驅動程式要釋放系統記憶體表面,執行時間會將系統記憶體表面DD_SURFACE_GLOBAL結構的 fpVidMem 指標成員設定為零,並呼叫顯示器驅動程式的 D3dCreateSurfaceEx 回呼。 除了釋放與此表面相關聯的所有資源之外,顯示驅動程式還必須清除先前儲存在 dwReserved1 成員中的資料。 請注意,因為視訊記憶體表面的 fpVidMem 指標成員可以設定為零,所以顯示驅動程式必須確認介面是否位於視訊或系統記憶體中,以判斷 對 D3dCreateSurfaceEx 的呼叫是否要通知與 dwSurfaceHandle 的視訊記憶體介面關聯,或通知系統記憶體表面與 dwSurfaceHandle的關聯。

不會呼叫 D3dCreateSurfaceEx 來通知與 dwSurfaceHandle解除視訊記憶體表面的關聯;顯示驅動程式的 DdDestroySurface 回呼必須處理本機和非本機視訊記憶體表面刪除,而且必須清除先前儲存在 dwReserved1 成員中的資料。

驅動程式也應該儲存使用表面時所需的任何表面相關資訊。 驅動程式必須為每個新的 lpDDLcl 建立新的表面資料表,並在必要時隱含放大資料表以容納更多表面。 一般而言,這是使用指數成長演算法來完成,因此您不需要太常放大資料表。 如需實作詳細資料,請參閱 Microsoft Windows 驅動程式開發工具組隨附的 Perm3 範例驅動程式 (DDK) 。 (DDK 前面有 Windows 驅動程式套件 [WDK].)

注意 Microsoft Windows 驅動程式套件 (WDK) 不包含 3Dlabs Permedia3 (Perm3.htm) 範例顯示驅動程式。 您可以從 Windows Server 2003 SP1 DDK 取得此範例驅動程式,您可以從 WDHC 網站的 DDK - Windows 驅動程式開發工具組 頁面下載。
 
Direct3D 會透過 Direct3D 執行時間或應用程式的要求,在 Surface 建立之後呼叫 D3dCreateSurfaceEx

D3dCreateSurfaceEx 只能針對系統記憶體表面使用已停用 的 PDEV 呼叫。 呼叫顯示器驅動程式的 DrvAssertMode 函式,以停用或啟用 PDEV。 如需詳細資訊 ,請參閱管理 PDEV

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);
    }
}

需求

   
目標平台 桌面
標頭 ddrawint.h (包含 Winddi.h)

另請參閱

D3DDP2OP_CLEAR

D3DDP2OP_SETRENDERTARGET

D3DDP2OP_TEXBLT

D3dDestroyDDLocal

D3dDrawPrimitives2

DD_CREATESURFACEEXDATA

DD_SURFACE_GLOBAL

DD_SURFACE_LOCAL

DD_SURFACE_MORE

DdDestroySurface