Поделиться через


функция обратного вызова 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 позволяет внедрить дескриптор поверхности в поток команд Direct3D. Например, когда маркер команды D3DDP2OP_TEXBLT отправляется в функцию D3dDrawPrimitives2 драйвера для загрузки карты текстуры, он использует дескриптор источника и дескриптор назначения, которые были связаны с поверхностью DirectDraw через D3dCreateSurfaceEx.

Для каждой поверхности DirectDraw, созданной в локальном объекте DirectDraw, среда выполнения создает допустимый дескриптор, который однозначно идентифицирует поверхность и помещает дескриптор в элемент dwSurfaceHandleструктуры DD_SURFACE_MORE . Элемент lpDDSLcl структуры DD_CREATESURFACEEXDATA в pcsxd указывает на структуру DD_SURFACE_LOCAL , содержащую элемент lpSurfMore , указывающий на этот DD_SURFACE_MORE. Это значение дескриптора также используется с состоянием D3DRENDERSTATE_TEXTUREHANDLE отрисовки для включения форматирования, а также с командами D3DDP2OP_SETRENDERTARGET и D3DDP2OP_CLEAR для задания и очистки новых буферов отрисовки и глубины. Драйвер должен завершить вызов и вернуть DDHAL_DRIVER_HANDLED, если ему не удается создать поверхность Direct3D.

Для поверхности системной памяти или области видеопамяти при вызове D3dCreateSurfaceEx для уведомления об ассоциации dwSurfaceHandle с DD_SURFACE_GLOBAL и DD_SURFACE_LOCAL структурами поверхности драйвер дисплея может хранить любые данные (например, указатель на выделенную в частном порядке память) в членах dwReserved1 DD_SURFACE_GLOBAL и DD_SURFACE_LOCAL, так как эти элементы зарезервированы драйвером дисплея для частного использования.

Чтобы уведомить драйвер дисплея о том, что поверхность системной памяти должна быть освобождена, среда выполнения задает элемент указателя fpVidMem структуры DD_SURFACE_GLOBAL поверхности системной памяти равным нулю и вызывает обратный вызов D3dCreateSurfaceEx драйвера дисплея. Помимо освобождения всех ресурсов, связанных с этой поверхностью, драйвер дисплея должен очистить данные, которые ранее хранились в элементах dwReserved1 . Обратите внимание, что поскольку элемент указателя fpVidMem для поверхности видеопамяти может быть равен нулю, драйвер дисплея должен проверить, находится ли поверхность в видео или системной памяти, чтобы определить, предназначен ли вызов D3dCreateSurfaceEx для уведомления о связи поверхности видеопамяти с dwSurfaceHandle или уведомления об отмене связи поверхности системной памяти с dwSurfaceHandle.

D3dCreateSurfaceEx не вызывается для уведомления об отмене связи поверхности видеопамяти с dwSurfaceHandle; обратный вызов DdDeтяжеяSurface драйвера дисплея должен обрабатывать удаление локальной и нелокальной поверхности видеопамяти и очищать данные, которые ранее хранились в членах dwReserved1 .

Драйвер также должен хранить все сведения, связанные с поверхностью, необходимые при использовании поверхности. Драйвер должен создать новую таблицу поверхностей для каждого нового lpDDLcl и неявно увеличить таблицу, когда это необходимо для размещения большего размера поверхностей. Как правило, это делается с помощью алгоритма экспоненциального роста, чтобы не увеличивать таблицу слишком часто. Дополнительные сведения о реализации см. в примере драйвера Perm3 , который входит в состав пакета средств разработки драйверов Microsoft Windows (DDK). (DDK предшествовал комплекту драйверов Windows [WDK].)

Примечание Пакет драйверов Microsoft Windows (WDK) не содержит пример драйвера дисплея 3Dlabs Permedia3 (Perm3.htm). Этот пример драйвера можно получить в DDK для Windows Server 2003 с пакетом обновления 1 (SP1), который можно скачать на странице комплекта средств разработки драйверов DDK для Windows на веб-сайте WDHC.
 
Direct3D вызывает D3dCreateSurfaceEx после создания поверхности DirectDraw по запросу среды выполнения Direct3D или приложения.

D3dCreateSurfaceEx можно вызвать только с отключенным PDEV для поверхности системной памяти. PDEV отключается или включается путем вызова функции DrvAssertMode драйвера дисплея. Дополнительные сведения см. в разделе Управление 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

D3dDeкистройDDLocal

D3dDrawPrimitives2

DD_CREATESURFACEEXDATA

DD_SURFACE_GLOBAL

DD_SURFACE_LOCAL

DD_SURFACE_MORE

DdDesurface