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_MORElpSurfMore 成员的DD_SURFACE_LOCAL结构。 此句柄值还用于D3DRENDERSTATE_TEXTUREHANDLE呈现状态以启用纹理,并与 D3DDP2OP_SETRENDERTARGETD3DDP2OP_CLEAR 命令一起使用,以设置和清除新的呈现缓冲区和深度缓冲区。 如果驱动程序无法创建 Direct3D 图面,则驱动程序应使调用失败并返回DDHAL_DRIVER_HANDLED。

对于系统内存图面或视频内存图面,当调用 D3dCreateSurfaceEx 来通知 dwSurfaceHandle 与图面 DD_SURFACE_GLOBALDD_SURFACE_LOCAL 结构的关联时,显示驱动程序可以存储任何数据 (例如,指向 dwReserved1 中专用分配的内存) 的指针1DD_SURFACE_GLOBAL 和 DD_SURFACE_LOCAL 的成员,因为这些成员保留供显示驱动程序专用。

为了通知显示驱动程序要释放系统内存图面,运行时将系统内存图面DD_SURFACE_GLOBAL结构的 fpVidMem 指针成员设置为零,并调用显示驱动程序的 D3dCreateSurfaceEx 回调。 除了释放与此图面关联的所有资源外,显示驱动程序还必须清除以前存储在 dwReserved1 成员中的数据。 请注意,由于视频内存图面的 fpVidMem 指针成员可以设置为零,因此显示驱动程序必须验证图面是否在视频内存中或系统内存中,以确定对 D3dCreateSurfaceEx 的 调用是否旨在通知视频内存图面与 dwSurfaceHandle 的关联,或者通知系统内存图面与 dwSurfaceHandle 的取消关联。

不调用 D3dCreateSurfaceEx 来通知视频内存图面与 dwSurfaceHandle 的取消关联;显示驱动程序的 DdDestroySurface 回调必须处理本地和非本地视频内存表面删除,并且必须清除以前存储在 dwReserved1 成员中的数据。

驱动程序还应存储使用 Surface 时所需的任何与图面相关的信息。 驱动程序必须为每个新的 lpDDLcl 创建新的图面表,并在必要时隐式放大表以容纳更多图面。 通常,这是使用指数增长算法完成的,这样就不必过于频繁地放大表。 有关实现详细信息,请参阅 Microsoft Windows 驱动程序开发工具包 (DDK) 附带的 Perm3 示例驱动程序。 (DDK 位于 Windows 驱动程序工具包 [WDK].)

注意 Microsoft Windows 驱动程序工具包 (WDK) 不包含 3Dlabs Permedia3 (Perm3.htm) 示例显示驱动程序。 可以从 Windows Server 2003 SP1 DDK 获取此示例驱动程序,可以从 WDHC 网站的 DDK - Windows 驱动程序开发工具包 页下载该驱动程序。
 
Direct3D 在 DirectDraw 根据 Direct3D 运行时或应用程序的请求创建图面后调用 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