Bagikan melalui


PDD_CREATESURFACEEX fungsi panggilan balik (ddrawint.h)

Fungsi D3dCreateSurfaceEx memberi tahu tentang asosiasi permukaan Microsoft DirectDraw dan nilai handel Microsoft Direct3D untuk memungkinkan pengaturan permukaan untuk penyajian Direct3D.

Sintaks

PDD_CREATESURFACEEX PddCreatesurfaceex;

DWORD PddCreatesurfaceex(
  PDD_CREATESURFACEEXDATA unnamedParam1
)
{...}

Parameter

unnamedParam1

Menunjuk ke struktur DD_CREATESURFACEEXDATA yang berisi informasi yang diperlukan driver untuk membuat permukaan.

Menampilkan nilai

D3dCreateSurfaceEx mengembalikan salah satu kode panggilan balik berikut:

Keterangan

Semua driver Direct3D harus mendukung D3dCreateSurfaceEx.

D3dCreateSurfaceEx membuat hubungan antara permukaan DirectDraw dan handel permukaan bilangan bulat kecil. Dengan membuat asosiasi ini antara handel dan permukaan DirectDraw, D3dCreateSurfaceEx memungkinkan handel permukaan disematkan di aliran perintah Direct3D. Misalnya, ketika token perintah D3DDP2OP_TEXBLT dikirim ke fungsi D3dDrawPrimitives2 driver untuk memuat peta tekstur, token tersebut menggunakan handel sumber dan handel tujuan yang terkait dengan permukaan DirectDraw melalui D3dCreateSurfaceEx.

Untuk setiap permukaan DirectDraw yang dibuat di bawah objek DirectDraw lokal, runtime menghasilkan handel yang valid yang secara unik mengidentifikasi permukaan dan menempatkan handel di anggota dwSurfaceHandle dari struktur DD_SURFACE_MORE . Anggota lpDDSLcl dari struktur DD_CREATESURFACEEXDATA di pcsxd menunjuk ke struktur DD_SURFACE_LOCAL yang berisi anggota lpSurfMore yang menunjuk ke DD_SURFACE_MORE ini. Nilai handel ini juga digunakan dengan status render D3DRENDERSTATE_TEXTUREHANDLE untuk mengaktifkan tekstur, dan dengan perintah D3DDP2OP_SETRENDERTARGET dan D3DDP2OP_CLEAR untuk mengatur dan menghapus penyajian baru dan buffer kedalaman. Driver harus gagal dalam panggilan dan mengembalikan DDHAL_DRIVER_HANDLED jika tidak dapat membuat permukaan Direct3D.

Untuk permukaan memori sistem atau permukaan memori video, ketika D3dCreateSurfaceEx dipanggil untuk memberi tahu tentang asosiasi dwSurfaceHandle dengan struktur DD_SURFACE_GLOBAL dan DD_SURFACE_LOCAL permukaan, driver tampilan dapat menyimpan data apa pun (misalnya, penunjuk ke memori yang dialokasikan secara privat) di dwReserved1 anggota DD_SURFACE_GLOBAL dan DD_SURFACE_LOCAL karena anggota ini dicadangkan untuk penggunaan pribadi oleh driver tampilan.

Untuk memberi tahu driver tampilan bahwa permukaan memori sistem akan dirilis, runtime mengatur anggota penunjuk fpVidMem dari struktur DD_SURFACE_GLOBAL permukaan memori sistem ke nol dan memanggil panggilan balik D3dCreateSurfaceEx driver tampilan. Selain merilis semua sumber daya yang terkait dengan permukaan ini, driver tampilan harus menghapus data yang sebelumnya disimpan di anggota dwReserved1 . Perhatikan bahwa karena anggota penunjuk fpVidMem untuk permukaan memori video dapat diatur ke nol, driver tampilan harus memverifikasi apakah permukaan berada dalam memori video atau sistem untuk menentukan apakah panggilan ke D3dCreateSurfaceEx dimaksudkan untuk memberi tahu tentang asosiasi permukaan memori video dengan dwSurfaceHandle atau untuk memberi tahu tentang disasosiasi permukaan memori sistem dari dwSurfaceHandle.

D3dCreateSurfaceEx tidak dipanggil untuk memberi tahu tentang disasosiasi permukaan memori video dari dwSurfaceHandle; panggilan balik DdDestroySurface driver tampilan harus menangani penghapusan permukaan memori video lokal dan nonlokal dan harus menghapus data yang sebelumnya disimpan di anggota dwReserved1 .

Driver juga harus menyimpan informasi terkait permukaan yang dibutuhkan saat menggunakan permukaan. Driver harus membuat tabel permukaan baru untuk setiap lpDDLcl baru dan secara implisit memperbesar tabel jika diperlukan untuk mengakomodasi lebih banyak permukaan. Biasanya, ini dilakukan dengan algoritma pertumbuhan eksponensial sehingga Anda tidak perlu memperbesar tabel terlalu sering. Lihat driver sampel Perm3 yang disertakan dengan Microsoft Windows Driver Development Kit (DDK) untuk detail implementasi. (DDK mendahului Windows Driver Kit [WDK].)

Catatan Microsoft Windows Driver Kit (WDK) tidak berisi driver tampilan sampel 3Dlabs Permedia3 (Perm3.htm). Anda bisa mendapatkan driver sampel ini dari Windows Server 2003 SP1 DDK, yang dapat Anda unduh dari halaman DDK - Windows Driver Development Kit dari situs web WDHC.
 
Direct3D memanggil D3dCreateSurfaceEx setelah permukaan dibuat oleh DirectDraw berdasarkan permintaan runtime Direct3D atau aplikasi.

D3dCreateSurfaceEx hanya dapat dipanggil dengan PDEV yang dinonaktifkan untuk permukaan memori sistem. PDEV dinonaktifkan atau diaktifkan dengan memanggil fungsi DrvAssertMode driver tampilan. Lihat Mengelola PDEV untuk informasi selengkapnya.

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

Persyaratan

   
Target Platform Desktop
Header ddrawint.h (termasuk Winddi.h)

Lihat juga

D3DDP2OP_CLEAR

D3DDP2OP_SETRENDERTARGET

D3DDP2OP_TEXBLT

D3dDestroyDDLocal

D3dDrawPrimitives2

DD_CREATESURFACEEXDATA

DD_SURFACE_GLOBAL

DD_SURFACE_LOCAL

DD_SURFACE_MORE

DdDestroySurface